Pull rust fixes from Miguel Ojeda: "Toolchain and infrastructure: - Pass '-Zunstable-options' flag required by the future Rust 1.95.0 - Fix 'objtool' warning for Rust 1.84.0 'kernel' crate: - 'irq' module: add missing bound detected by the future Rust 1.95.0 - 'list' module: add missing 'unsafe' blocks and placeholder safety comments to macros (an issue for future callers within the crate) 'pin-init' crate: - Clean Clippy warning that changed behavior in the future Rust 1.95.0" * tag 'rust-fixes-7.0' of git://git.kernel.org/pub/scm/linux/kernel/git/ojeda/linux: rust: list: Add unsafe blocks for container_of and safety comments rust: pin-init: replace clippy `expect` with `allow` rust: irq: add `'static` bounds to irq callbacks objtool/rust: add one more `noreturn` Rust function rust: kbuild: pass `-Zunstable-options` for Rust 1.95.0
Unified · Split
| @@ -570,6 +570,8 @@ $(obj)/$(libpin_init_internal_name): $(src)/pin-init/internal/src/lib.rs \ · 569 unmodified lines | |||
| 570 | $(obj)/libproc_macro2.rlib $(obj)/libquote.rlib $(obj)/libsyn.rlib FORCE | 570 | $(obj)/libproc_macro2.rlib $(obj)/libquote.rlib $(obj)/libsyn.rlib FORCE |
| 571 | +$(call if_changed_dep,rustc_procmacro) | 571 | +$(call if_changed_dep,rustc_procmacro) |
| 572 | 572 | ||
| 573 | # `rustc` requires `-Zunstable-options` to use custom target specifications | ||
| 574 | # since Rust 1.95.0 (https://github.com/rust-lang/rust/pull/151534). | ||
| 573 | quiet_cmd_rustc_library = $(if $(skip_clippy),RUSTC,$(RUSTC_OR_CLIPPY_QUIET)) L $@ | 575 | quiet_cmd_rustc_library = $(if $(skip_clippy),RUSTC,$(RUSTC_OR_CLIPPY_QUIET)) L $@ |
| 574 | cmd_rustc_library = \ | 576 | cmd_rustc_library = \ |
| 575 | OBJTREE=$(abspath $(objtree)) \ | 577 | OBJTREE=$(abspath $(objtree)) \ |
| @@ -580,6 +582,7 @@ quiet_cmd_rustc_library = $(if $(skip_clippy),RUSTC,$(RUSTC_OR_CLIPPY_QUIET)) L · 4 unmodified lines | |||
| 580 | --crate-type rlib -L$(objtree)/$(obj) \ | 582 | --crate-type rlib -L$(objtree)/$(obj) \ |
| 581 | --crate-name $(patsubst %.o,%,$(notdir $@)) $< \ | 583 | --crate-name $(patsubst %.o,%,$(notdir $@)) $< \ |
| 582 | --sysroot=/dev/null \ | 584 | --sysroot=/dev/null \ |
| 585 | -Zunstable-options \ | ||
| 583 | $(if $(rustc_objcopy),;$(OBJCOPY) $(rustc_objcopy) $@) \ | 586 | $(if $(rustc_objcopy),;$(OBJCOPY) $(rustc_objcopy) $@) \ |
| 584 | $(cmd_objtool) | 587 | $(cmd_objtool) |
| 585 | 588 | ||
| @@ -260,7 +260,10 @@ impl<T: Handler + 'static> Registration<T> { · 259 unmodified lines | |||
| 260 | /// # Safety | 260 | /// # Safety |
| 261 | /// | 261 | /// |
| 262 | /// This function should be only used as the callback in `request_irq`. | 262 | /// This function should be only used as the callback in `request_irq`. |
| 263 | unsafe extern "C" fn handle_irq_callback<T: Handler>(_irq: i32, ptr: *mut c_void) -> c_uint { | 263 | unsafe extern "C" fn handle_irq_callback<T: Handler + 'static>( |
| 264 | _irq: i32, | ||
| 265 | ptr: *mut c_void, | ||
| 266 | ) -> c_uint { | ||
| 264 | // SAFETY: `ptr` is a pointer to `Registration<T>` set in `Registration::new` | 267 | // SAFETY: `ptr` is a pointer to `Registration<T>` set in `Registration::new` |
| 265 | let registration = unsafe { &*(ptr as *const Registration<T>) }; | 268 | let registration = unsafe { &*(ptr as *const Registration<T>) }; |
| 266 | // SAFETY: The irq callback is removed before the device is unbound, so the fact that the irq | 269 | // SAFETY: The irq callback is removed before the device is unbound, so the fact that the irq |
| @@ -478,7 +481,7 @@ impl<T: ThreadedHandler + 'static> ThreadedRegistration<T> { · 211 unmodified lines | |||
| 478 | /// # Safety | 481 | /// # Safety |
| 479 | /// | 482 | /// |
| 480 | /// This function should be only used as the callback in `request_threaded_irq`. | 483 | /// This function should be only used as the callback in `request_threaded_irq`. |
| 481 | unsafe extern "C" fn handle_threaded_irq_callback<T: ThreadedHandler>( | 484 | unsafe extern "C" fn handle_threaded_irq_callback<T: ThreadedHandler + 'static>( |
| 482 | _irq: i32, | 485 | _irq: i32, |
| 483 | ptr: *mut c_void, | 486 | ptr: *mut c_void, |
| 484 | ) -> c_uint { | 487 | ) -> c_uint { |
| @@ -494,7 +497,10 @@ unsafe extern "C" fn handle_threaded_irq_callback<T: ThreadedHandler>( · 9 unmodified lines | |||
| 494 | /// # Safety | 497 | /// # Safety |
| 495 | /// | 498 | /// |
| 496 | /// This function should be only used as the callback in `request_threaded_irq`. | 499 | /// This function should be only used as the callback in `request_threaded_irq`. |
| 497 | unsafe extern "C" fn thread_fn_callback<T: ThreadedHandler>(_irq: i32, ptr: *mut c_void) -> c_uint { | 500 | unsafe extern "C" fn thread_fn_callback<T: ThreadedHandler + 'static>( |
| 501 | _irq: i32, | ||
| 502 | ptr: *mut c_void, | ||
| 503 | ) -> c_uint { | ||
| 498 | // SAFETY: `ptr` is a pointer to `ThreadedRegistration<T>` set in `ThreadedRegistration::new` | 504 | // SAFETY: `ptr` is a pointer to `ThreadedRegistration<T>` set in `ThreadedRegistration::new` |
| 499 | let registration = unsafe { &*(ptr as *const ThreadedRegistration<T>) }; | 505 | let registration = unsafe { &*(ptr as *const ThreadedRegistration<T>) }; |
| 500 | // SAFETY: The irq callback is removed before the device is unbound, so the fact that the irq | 506 | // SAFETY: The irq callback is removed before the device is unbound, so the fact that the irq |
| @@ -84,11 +84,12 @@ macro_rules! impl_has_list_links_self_ptr { · 83 unmodified lines | |||
| 84 | // right type. | 84 | // right type. |
| 85 | unsafe impl$(<$($generics)*>)? $crate::list::HasSelfPtr<$item_type $(, $id)?> for $self {} | 85 | unsafe impl$(<$($generics)*>)? $crate::list::HasSelfPtr<$item_type $(, $id)?> for $self {} |
| 86 | 86 | ||
| 87 | // SAFETY: TODO. | ||
| 87 | unsafe impl$(<$($generics)*>)? $crate::list::HasListLinks$(<$id>)? for $self { | 88 | unsafe impl$(<$($generics)*>)? $crate::list::HasListLinks$(<$id>)? for $self { |
| 88 | #[inline] | 89 | #[inline] |
| 89 | unsafe fn raw_get_list_links(ptr: *mut Self) -> *mut $crate::list::ListLinks$(<$id>)? { | 90 | unsafe fn raw_get_list_links(ptr: *mut Self) -> *mut $crate::list::ListLinks$(<$id>)? { |
| 90 | // SAFETY: The caller promises that the pointer is not dangling. | ||
| 91 | let ptr: *mut $crate::list::ListLinksSelfPtr<$item_type $(, $id)?> = | 91 | let ptr: *mut $crate::list::ListLinksSelfPtr<$item_type $(, $id)?> = |
| 92 | // SAFETY: The caller promises that the pointer is not dangling. | ||
| 92 | unsafe { ::core::ptr::addr_of_mut!((*ptr)$(.$field)*) }; | 93 | unsafe { ::core::ptr::addr_of_mut!((*ptr)$(.$field)*) }; |
| 93 | ptr.cast() | 94 | ptr.cast() |
| 94 | } | 95 | } |
| @@ -217,7 +218,7 @@ macro_rules! impl_list_item { · 122 unmodified lines | |||
| 217 | // SAFETY: `me` originates from the most recent call to `prepare_to_insert`, so it | 218 | // SAFETY: `me` originates from the most recent call to `prepare_to_insert`, so it |
| 218 | // points at the field `$field` in a value of type `Self`. Thus, reversing that | 219 | // points at the field `$field` in a value of type `Self`. Thus, reversing that |
| 219 | // operation is still in-bounds of the allocation. | 220 | // operation is still in-bounds of the allocation. |
| 220 | $crate::container_of!(me, Self, $($field).*) | 221 | unsafe { $crate::container_of!(me, Self, $($field).*) } |
| 221 | } | 222 | } |
| 222 | 223 | ||
| 223 | // GUARANTEES: | 224 | // GUARANTEES: |
| @@ -242,7 +243,7 @@ macro_rules! impl_list_item { · 18 unmodified lines | |||
| 242 | // SAFETY: `me` originates from the most recent call to `prepare_to_insert`, so it | 243 | // SAFETY: `me` originates from the most recent call to `prepare_to_insert`, so it |
| 243 | // points at the field `$field` in a value of type `Self`. Thus, reversing that | 244 | // points at the field `$field` in a value of type `Self`. Thus, reversing that |
| 244 | // operation is still in-bounds of the allocation. | 245 | // operation is still in-bounds of the allocation. |
| 245 | $crate::container_of!(me, Self, $($field).*) | 246 | unsafe { $crate::container_of!(me, Self, $($field).*) } |
| 246 | } | 247 | } |
| 247 | } | 248 | } |
| 248 | )*}; | 249 | )*}; |
| @@ -270,9 +271,12 @@ macro_rules! impl_list_item { · 21 unmodified lines | |||
| 270 | // SAFETY: The caller promises that `me` points at a valid value of type `Self`. | 271 | // SAFETY: The caller promises that `me` points at a valid value of type `Self`. |
| 271 | let links_field = unsafe { <Self as $crate::list::ListItem<$num>>::view_links(me) }; | 272 | let links_field = unsafe { <Self as $crate::list::ListItem<$num>>::view_links(me) }; |
| 272 | 273 | ||
| 273 | let container = $crate::container_of!( | 274 | // SAFETY: TODO. |
| 274 | links_field, $crate::list::ListLinksSelfPtr<Self, $num>, inner | 275 | let container = unsafe { |
| 275 | ); | 276 | $crate::container_of!( |
| 277 | links_field, $crate::list::ListLinksSelfPtr<Self, $num>, inner | ||
| 278 | ) | ||
| 279 | }; | ||
| 276 | 280 | ||
| 277 | // SAFETY: By the same reasoning above, `links_field` is a valid pointer. | 281 | // SAFETY: By the same reasoning above, `links_field` is a valid pointer. |
| 278 | let self_ptr = unsafe { | 282 | let self_ptr = unsafe { |
| @@ -319,9 +323,12 @@ macro_rules! impl_list_item { · 40 unmodified lines | |||
| 319 | // `ListArc` containing `Self` until the next call to `post_remove`. The value cannot | 323 | // `ListArc` containing `Self` until the next call to `post_remove`. The value cannot |
| 320 | // be destroyed while a `ListArc` reference exists. | 324 | // be destroyed while a `ListArc` reference exists. |
| 321 | unsafe fn view_value(links_field: *mut $crate::list::ListLinks<$num>) -> *const Self { | 325 | unsafe fn view_value(links_field: *mut $crate::list::ListLinks<$num>) -> *const Self { |
| 322 | let container = $crate::container_of!( | 326 | // SAFETY: TODO. |
| 323 | links_field, $crate::list::ListLinksSelfPtr<Self, $num>, inner | 327 | let container = unsafe { |
| 324 | ); | 328 | $crate::container_of!( |
| 329 | links_field, $crate::list::ListLinksSelfPtr<Self, $num>, inner | ||
| 330 | ) | ||
| 331 | }; | ||
| 325 | 332 | ||
| 326 | // SAFETY: By the same reasoning above, `links_field` is a valid pointer. | 333 | // SAFETY: By the same reasoning above, `links_field` is a valid pointer. |
| 327 | let self_ptr = unsafe { | 334 | let self_ptr = unsafe { |
| @@ -1143,13 +1143,13 @@ pub const unsafe fn init_from_closure<T: ?Sized, E>( · 1142 unmodified lines | |||
| 1143 | /// | 1143 | /// |
| 1144 | /// - `*mut U` must be castable to `*mut T` and any value of type `T` written through such a | 1144 | /// - `*mut U` must be castable to `*mut T` and any value of type `T` written through such a |
| 1145 | /// pointer must result in a valid `U`. | 1145 | /// pointer must result in a valid `U`. |
| 1146 | #[expect(clippy::let_and_return)] | ||
| 1147 | pub const unsafe fn cast_pin_init<T, U, E>(init: impl PinInit<T, E>) -> impl PinInit<U, E> { | 1146 | pub const unsafe fn cast_pin_init<T, U, E>(init: impl PinInit<T, E>) -> impl PinInit<U, E> { |
| 1148 | // SAFETY: initialization delegated to a valid initializer. Cast is valid by function safety | 1147 | // SAFETY: initialization delegated to a valid initializer. Cast is valid by function safety |
| 1149 | // requirements. | 1148 | // requirements. |
| 1150 | let res = unsafe { pin_init_from_closure(|ptr: *mut U| init.__pinned_init(ptr.cast::<T>())) }; | 1149 | let res = unsafe { pin_init_from_closure(|ptr: *mut U| init.__pinned_init(ptr.cast::<T>())) }; |
| 1151 | // FIXME: remove the let statement once the nightly-MSRV allows it (1.78 otherwise encounters a | 1150 | // FIXME: remove the let statement once the nightly-MSRV allows it (1.78 otherwise encounters a |
| 1152 | // cycle when computing the type returned by this function) | 1151 | // cycle when computing the type returned by this function) |
| 1152 | #[allow(clippy::let_and_return)] | ||
| 1153 | res | 1153 | res |
| 1154 | } | 1154 | } |
| 1155 | 1155 | ||
| @@ -1159,13 +1159,13 @@ pub const unsafe fn cast_pin_init<T, U, E>(init: impl PinInit<T, E>) -> impl Pin · 3 unmodified lines | |||
| 1159 | /// | 1159 | /// |
| 1160 | /// - `*mut U` must be castable to `*mut T` and any value of type `T` written through such a | 1160 | /// - `*mut U` must be castable to `*mut T` and any value of type `T` written through such a |
| 1161 | /// pointer must result in a valid `U`. | 1161 | /// pointer must result in a valid `U`. |
| 1162 | #[expect(clippy::let_and_return)] | ||
| 1163 | pub const unsafe fn cast_init<T, U, E>(init: impl Init<T, E>) -> impl Init<U, E> { | 1162 | pub const unsafe fn cast_init<T, U, E>(init: impl Init<T, E>) -> impl Init<U, E> { |
| 1164 | // SAFETY: initialization delegated to a valid initializer. Cast is valid by function safety | 1163 | // SAFETY: initialization delegated to a valid initializer. Cast is valid by function safety |
| 1165 | // requirements. | 1164 | // requirements. |
| 1166 | let res = unsafe { init_from_closure(|ptr: *mut U| init.__init(ptr.cast::<T>())) }; | 1165 | let res = unsafe { init_from_closure(|ptr: *mut U| init.__init(ptr.cast::<T>())) }; |
| 1167 | // FIXME: remove the let statement once the nightly-MSRV allows it (1.78 otherwise encounters a | 1166 | // FIXME: remove the let statement once the nightly-MSRV allows it (1.78 otherwise encounters a |
| 1168 | // cycle when computing the type returned by this function) | 1167 | // cycle when computing the type returned by this function) |
| 1168 | #[allow(clippy::let_and_return)] | ||
| 1169 | res | 1169 | res |
| 1170 | } | 1170 | } |
| 1171 | 1171 | ||
| @@ -197,7 +197,8 @@ static bool is_rust_noreturn(const struct symbol *func) · 196 unmodified lines | |||
| 197 | * as well as changes to the source code itself between versions (since | 197 | * as well as changes to the source code itself between versions (since |
| 198 | * these come from the Rust standard library). | 198 | * these come from the Rust standard library). |
| 199 | */ | 199 | */ |
| 200 | return str_ends_with(func->name, "_4core3num22from_ascii_radix_panic") || | 200 | return str_ends_with(func->name, "_4core3num20from_str_radix_panic") || |
| 201 | str_ends_with(func->name, "_4core3num22from_ascii_radix_panic") || | ||
| 201 | str_ends_with(func->name, "_4core5sliceSp15copy_from_slice17len_mismatch_fail") || | 202 | str_ends_with(func->name, "_4core5sliceSp15copy_from_slice17len_mismatch_fail") || |
| 202 | str_ends_with(func->name, "_4core6option13expect_failed") || | 203 | str_ends_with(func->name, "_4core6option13expect_failed") || |
| 203 | str_ends_with(func->name, "_4core6option13unwrap_failed") || | 204 | str_ends_with(func->name, "_4core6option13unwrap_failed") || |