History

rust: enable `clippy::undocumented_unsafe_blocks` lint

Checking that we are not missing any `// SAFETY` comments in our `unsafe` blocks is something we have wanted to do for a long time, as well as cleaning up the remaining cases that were not documented [1]. Back when Rust for Linux started, this was something that could have been done via a script, like Rust's `tidy`. Soon after, in Rust 1.58.0, Clippy implemented the `undocumented_unsafe_blocks` lint [2]. Even though the lint has a few false positives, e.g. in some cases where attributes appear between the comment and the `unsafe` block [3], there are workarounds and the lint seems quite usable already. Thus enable the lint now. We still have a few cases to clean up, so just allow those for the moment by writing a `TODO` comment -- some of those may be good candidates for new contributors.

Miguel Ojeda committed 2 years ago

Commit db4f72c1 parent 567cdff16 files · +47 −10Browse files

Unified · Split

16 files
  1. Makefile +1 −0
  2. mm/kasan/kasan_test_rust.rs +1 −0
  3. rust/bindings/lib.rs +1 −0
  4. rust/kernel/alloc/allocator.rs +2 −0
  5. rust/kernel/error.rs +6 −3
  6. rust/kernel/init.rs +5 −0
  7. rust/kernel/init/__internal.rs +2 −0
  8. rust/kernel/init/macros.rs +9 −0
  9. rust/kernel/list.rs +1 −0
  10. rust/kernel/print.rs +2 −0
  11. rust/kernel/str.rs +4 −3
  12. rust/kernel/sync/condvar.rs +1 −1
  13. rust/kernel/sync/lock.rs +3 −3
  14. rust/kernel/types.rs +4 −0
  15. rust/kernel/workqueue.rs +4 −0
  16. rust/uapi/lib.rs +1 −0
Makefile+1−0
@@ -457,6 +457,7 @@ export rust_common_flags := --edition=2021 \ · 456 unmodified lines
457 -Wclippy::needless_bitwise_bool \457 -Wclippy::needless_bitwise_bool \
458 -Wclippy::needless_continue \458 -Wclippy::needless_continue \
459 -Wclippy::no_mangle_with_rust_abi \459 -Wclippy::no_mangle_with_rust_abi \
460 -Wclippy::undocumented_unsafe_blocks \
460 -Wrustdoc::missing_crate_level_docs461 -Wrustdoc::missing_crate_level_docs
461 462
462KBUILD_HOSTCFLAGS := $(KBUILD_USERHOSTCFLAGS) $(HOST_LFS_CFLAGS) \463KBUILD_HOSTCFLAGS := $(KBUILD_USERHOSTCFLAGS) $(HOST_LFS_CFLAGS) \
mm/kasan/kasan_test_rust.rs+1−0
@@ -17,5 +17,6 @@ pub extern "C" fn kasan_test_rust_uaf() -> u8 { · 16 unmodified lines
17 }17 }
18 let ptr: *mut u8 = addr_of_mut!(v[2048]);18 let ptr: *mut u8 = addr_of_mut!(v[2048]);
19 drop(v);19 drop(v);
20 // SAFETY: Incorrect, on purpose.
20 unsafe { *ptr }21 unsafe { *ptr }
21}22}
rust/bindings/lib.rs+1−0
@@ -25,6 +25,7 @@ · 24 unmodified lines
25)]25)]
26 26
27#[allow(dead_code)]27#[allow(dead_code)]
28#[allow(clippy::undocumented_unsafe_blocks)]
28mod bindings_raw {29mod bindings_raw {
29 // Use glob import here to expose all helpers.30 // Use glob import here to expose all helpers.
30 // Symbols defined within the module will take precedence to the glob import.31 // Symbols defined within the module will take precedence to the glob import.
rust/kernel/alloc/allocator.rs+2−0
@@ -31,6 +31,7 @@ pub(crate) unsafe fn krealloc_aligned(ptr: *mut u8, new_layout: Layout, flags: F · 30 unmodified lines
31 unsafe { bindings::krealloc(ptr as *const core::ffi::c_void, size, flags.0) as *mut u8 }31 unsafe { bindings::krealloc(ptr as *const core::ffi::c_void, size, flags.0) as *mut u8 }
32}32}
33 33
34// SAFETY: TODO.
34unsafe impl GlobalAlloc for KernelAllocator {35unsafe impl GlobalAlloc for KernelAllocator {
35 unsafe fn alloc(&self, layout: Layout) -> *mut u8 {36 unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
36 // SAFETY: `ptr::null_mut()` is null and `layout` has a non-zero size by the function safety37 // SAFETY: `ptr::null_mut()` is null and `layout` has a non-zero size by the function safety
@@ -39,6 +40,7 @@ unsafe impl GlobalAlloc for KernelAllocator { · 2 unmodified lines
39 }40 }
40 41
41 unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) {42 unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) {
43 // SAFETY: TODO.
42 unsafe {44 unsafe {
43 bindings::kfree(ptr as *const core::ffi::c_void);45 bindings::kfree(ptr as *const core::ffi::c_void);
44 }46 }
rust/kernel/error.rs+6−3
@@ -171,9 +171,11 @@ impl fmt::Debug for Error { · 170 unmodified lines
171 match self.name() {171 match self.name() {
172 // Print out number if no name can be found.172 // Print out number if no name can be found.
173 None => f.debug_tuple("Error").field(&-self.0).finish(),173 None => f.debug_tuple("Error").field(&-self.0).finish(),
174 // SAFETY: These strings are ASCII-only.
175 Some(name) => f174 Some(name) => f
176 .debug_tuple(unsafe { core::str::from_utf8_unchecked(name) })175 .debug_tuple(
176 // SAFETY: These strings are ASCII-only.
177 unsafe { core::str::from_utf8_unchecked(name) },
178 )
177 .finish(),179 .finish(),
178 }180 }
179 }181 }
@@ -277,6 +279,8 @@ pub(crate) fn from_err_ptr<T>(ptr: *mut T) -> Result<*mut T> { · 97 unmodified lines
277 if unsafe { bindings::IS_ERR(const_ptr) } {279 if unsafe { bindings::IS_ERR(const_ptr) } {
278 // SAFETY: The FFI function does not deref the pointer.280 // SAFETY: The FFI function does not deref the pointer.
279 let err = unsafe { bindings::PTR_ERR(const_ptr) };281 let err = unsafe { bindings::PTR_ERR(const_ptr) };
282
283 #[allow(clippy::unnecessary_cast)]
280 // CAST: If `IS_ERR()` returns `true`,284 // CAST: If `IS_ERR()` returns `true`,
281 // then `PTR_ERR()` is guaranteed to return a285 // then `PTR_ERR()` is guaranteed to return a
282 // negative value greater-or-equal to `-bindings::MAX_ERRNO`,286 // negative value greater-or-equal to `-bindings::MAX_ERRNO`,
@@ -286,7 +290,6 @@ pub(crate) fn from_err_ptr<T>(ptr: *mut T) -> Result<*mut T> { · 3 unmodified lines
286 //290 //
287 // SAFETY: `IS_ERR()` ensures `err` is a291 // SAFETY: `IS_ERR()` ensures `err` is a
288 // negative value greater-or-equal to `-bindings::MAX_ERRNO`.292 // negative value greater-or-equal to `-bindings::MAX_ERRNO`.
289 #[allow(clippy::unnecessary_cast)]
290 return Err(unsafe { Error::from_errno_unchecked(err as core::ffi::c_int) });293 return Err(unsafe { Error::from_errno_unchecked(err as core::ffi::c_int) });
291 }294 }
292 Ok(ptr)295 Ok(ptr)
rust/kernel/init.rs+5−0
@@ -541,6 +541,7 @@ macro_rules! stack_try_pin_init { · 540 unmodified lines
541/// }541/// }
542/// pin_init!(&this in Buf {542/// pin_init!(&this in Buf {
543/// buf: [0; 64],543/// buf: [0; 64],
544/// // SAFETY: TODO.
544/// ptr: unsafe { addr_of_mut!((*this.as_ptr()).buf).cast() },545/// ptr: unsafe { addr_of_mut!((*this.as_ptr()).buf).cast() },
545/// pin: PhantomPinned,546/// pin: PhantomPinned,
546/// });547/// });
@@ -875,6 +876,7 @@ pub unsafe trait PinInit<T: ?Sized, E = Infallible>: Sized { · 328 unmodified lines
875 /// }876 /// }
876 ///877 ///
877 /// let foo = pin_init!(Foo {878 /// let foo = pin_init!(Foo {
879 /// // SAFETY: TODO.
878 /// raw <- unsafe {880 /// raw <- unsafe {
879 /// Opaque::ffi_init(|s| {881 /// Opaque::ffi_init(|s| {
880 /// init_foo(s);882 /// init_foo(s);
@@ -1162,6 +1164,7 @@ where · 281 unmodified lines
1162// SAFETY: Every type can be initialized by-value.1164// SAFETY: Every type can be initialized by-value.
1163unsafe impl<T, E> Init<T, E> for T {1165unsafe impl<T, E> Init<T, E> for T {
1164 unsafe fn __init(self, slot: *mut T) -> Result<(), E> {1166 unsafe fn __init(self, slot: *mut T) -> Result<(), E> {
1167 // SAFETY: TODO.
1165 unsafe { slot.write(self) };1168 unsafe { slot.write(self) };
1166 Ok(())1169 Ok(())
1167 }1170 }
@@ -1170,6 +1173,7 @@ unsafe impl<T, E> Init<T, E> for T { · 2 unmodified lines
1170// SAFETY: Every type can be initialized by-value. `__pinned_init` calls `__init`.1173// SAFETY: Every type can be initialized by-value. `__pinned_init` calls `__init`.
1171unsafe impl<T, E> PinInit<T, E> for T {1174unsafe impl<T, E> PinInit<T, E> for T {
1172 unsafe fn __pinned_init(self, slot: *mut T) -> Result<(), E> {1175 unsafe fn __pinned_init(self, slot: *mut T) -> Result<(), E> {
1176 // SAFETY: TODO.
1173 unsafe { self.__init(slot) }1177 unsafe { self.__init(slot) }
1174 }1178 }
1175}1179}
@@ -1411,6 +1415,7 @@ pub fn zeroed<T: Zeroable>() -> impl Init<T> { · 235 unmodified lines
1411 1415
1412macro_rules! impl_zeroable {1416macro_rules! impl_zeroable {
1413 ($($({$($generics:tt)*})? $t:ty, )*) => {1417 ($($({$($generics:tt)*})? $t:ty, )*) => {
1418 // SAFETY: Safety comments written in the macro invocation.
1414 $(unsafe impl$($($generics)*)? Zeroable for $t {})*1419 $(unsafe impl$($($generics)*)? Zeroable for $t {})*
1415 };1420 };
1416}1421}
rust/kernel/init/__internal.rs+2−0
@@ -112,10 +112,12 @@ impl<T: ?Sized> Clone for AllData<T> { · 111 unmodified lines
112 112
113impl<T: ?Sized> Copy for AllData<T> {}113impl<T: ?Sized> Copy for AllData<T> {}
114 114
115// SAFETY: TODO.
115unsafe impl<T: ?Sized> InitData for AllData<T> {116unsafe impl<T: ?Sized> InitData for AllData<T> {
116 type Datee = T;117 type Datee = T;
117}118}
118 119
120// SAFETY: TODO.
119unsafe impl<T: ?Sized> HasInitData for T {121unsafe impl<T: ?Sized> HasInitData for T {
120 type InitData = AllData<T>;122 type InitData = AllData<T>;
121 123
rust/kernel/init/macros.rs+9−0
@@ -513,6 +513,7 @@ macro_rules! __pinned_drop { · 512 unmodified lines
513 }513 }
514 ),514 ),
515 ) => {515 ) => {
516 // SAFETY: TODO.
516 unsafe $($impl_sig)* {517 unsafe $($impl_sig)* {
517 // Inherit all attributes and the type/ident tokens for the signature.518 // Inherit all attributes and the type/ident tokens for the signature.
518 $(#[$($attr)*])*519 $(#[$($attr)*])*
@@ -872,6 +873,7 @@ macro_rules! __pin_data { · 353 unmodified lines
872 }873 }
873 }874 }
874 875
876 // SAFETY: TODO.
875 unsafe impl<$($impl_generics)*>877 unsafe impl<$($impl_generics)*>
876 $crate::init::__internal::PinData for __ThePinData<$($ty_generics)*>878 $crate::init::__internal::PinData for __ThePinData<$($ty_generics)*>
877 where $($whr)*879 where $($whr)*
@@ -997,6 +999,7 @@ macro_rules! __pin_data { · 119 unmodified lines
997 slot: *mut $p_type,999 slot: *mut $p_type,
998 init: impl $crate::init::PinInit<$p_type, E>,1000 init: impl $crate::init::PinInit<$p_type, E>,
999 ) -> ::core::result::Result<(), E> {1001 ) -> ::core::result::Result<(), E> {
1002 // SAFETY: TODO.
1000 unsafe { $crate::init::PinInit::__pinned_init(init, slot) }1003 unsafe { $crate::init::PinInit::__pinned_init(init, slot) }
1001 }1004 }
1002 )*1005 )*
@@ -1007,6 +1010,7 @@ macro_rules! __pin_data { · 4 unmodified lines
1007 slot: *mut $type,1010 slot: *mut $type,
1008 init: impl $crate::init::Init<$type, E>,1011 init: impl $crate::init::Init<$type, E>,
1009 ) -> ::core::result::Result<(), E> {1012 ) -> ::core::result::Result<(), E> {
1013 // SAFETY: TODO.
1010 unsafe { $crate::init::Init::__init(init, slot) }1014 unsafe { $crate::init::Init::__init(init, slot) }
1011 }1015 }
1012 )*1016 )*
@@ -1121,6 +1125,8 @@ macro_rules! __init_internal { · 108 unmodified lines
1121 // no possibility of returning without `unsafe`.1125 // no possibility of returning without `unsafe`.
1122 struct __InitOk;1126 struct __InitOk;
1123 // Get the data about fields from the supplied type.1127 // Get the data about fields from the supplied type.
1128 //
1129 // SAFETY: TODO.
1124 let data = unsafe {1130 let data = unsafe {
1125 use $crate::init::__internal::$has_data;1131 use $crate::init::__internal::$has_data;
1126 // Here we abuse `paste!` to retokenize `$t`. Declarative macros have some internal1132 // Here we abuse `paste!` to retokenize `$t`. Declarative macros have some internal
@@ -1176,6 +1182,7 @@ macro_rules! __init_internal { · 49 unmodified lines
1176 let init = move |slot| -> ::core::result::Result<(), $err> {1182 let init = move |slot| -> ::core::result::Result<(), $err> {
1177 init(slot).map(|__InitOk| ())1183 init(slot).map(|__InitOk| ())
1178 };1184 };
1185 // SAFETY: TODO.
1179 let init = unsafe { $crate::init::$construct_closure::<_, $err>(init) };1186 let init = unsafe { $crate::init::$construct_closure::<_, $err>(init) };
1180 init1187 init
1181 }};1188 }};
@@ -1324,6 +1331,8 @@ macro_rules! __init_internal { · 142 unmodified lines
1324 // Endpoint, nothing more to munch, create the initializer.1331 // Endpoint, nothing more to munch, create the initializer.
1325 // Since we are in the closure that is never called, this will never get executed.1332 // Since we are in the closure that is never called, this will never get executed.
1326 // We abuse `slot` to get the correct type inference here:1333 // We abuse `slot` to get the correct type inference here:
1334 //
1335 // SAFETY: TODO.
1327 unsafe {1336 unsafe {
1328 // Here we abuse `paste!` to retokenize `$t`. Declarative macros have some internal1337 // Here we abuse `paste!` to retokenize `$t`. Declarative macros have some internal
1329 // information that is associated to already parsed fragments, so a path fragment1338 // information that is associated to already parsed fragments, so a path fragment
rust/kernel/list.rs+1−0
@@ -354,6 +354,7 @@ impl<T: ?Sized + ListItem<ID>, const ID: u64> List<T, ID> { · 353 unmodified lines
354 ///354 ///
355 /// `item` must not be in a different linked list (with the same id).355 /// `item` must not be in a different linked list (with the same id).
356 pub unsafe fn remove(&mut self, item: &T) -> Option<ListArc<T, ID>> {356 pub unsafe fn remove(&mut self, item: &T) -> Option<ListArc<T, ID>> {
357 // SAFETY: TODO.
357 let mut item = unsafe { ListLinks::fields(T::view_links(item)) };358 let mut item = unsafe { ListLinks::fields(T::view_links(item)) };
358 // SAFETY: The user provided a reference, and reference are never dangling.359 // SAFETY: The user provided a reference, and reference are never dangling.
359 //360 //
rust/kernel/print.rs+2−0
@@ -23,6 +23,7 @@ unsafe extern "C" fn rust_fmt_argument( · 22 unmodified lines
23 use fmt::Write;23 use fmt::Write;
24 // SAFETY: The C contract guarantees that `buf` is valid if it's less than `end`.24 // SAFETY: The C contract guarantees that `buf` is valid if it's less than `end`.
25 let mut w = unsafe { RawFormatter::from_ptrs(buf.cast(), end.cast()) };25 let mut w = unsafe { RawFormatter::from_ptrs(buf.cast(), end.cast()) };
26 // SAFETY: TODO.
26 let _ = w.write_fmt(unsafe { *(ptr as *const fmt::Arguments<'_>) });27 let _ = w.write_fmt(unsafe { *(ptr as *const fmt::Arguments<'_>) });
27 w.pos().cast()28 w.pos().cast()
28}29}
@@ -102,6 +103,7 @@ pub unsafe fn call_printk( · 73 unmodified lines
102) {103) {
103 // `_printk` does not seem to fail in any path.104 // `_printk` does not seem to fail in any path.
104 #[cfg(CONFIG_PRINTK)]105 #[cfg(CONFIG_PRINTK)]
106 // SAFETY: TODO.
105 unsafe {107 unsafe {
106 bindings::_printk(108 bindings::_printk(
107 format_string.as_ptr() as _,109 format_string.as_ptr() as _,
rust/kernel/str.rs+4−3
@@ -162,10 +162,10 @@ impl CStr { · 161 unmodified lines
162 /// Returns the length of this string with `NUL`.162 /// Returns the length of this string with `NUL`.
163 #[inline]163 #[inline]
164 pub const fn len_with_nul(&self) -> usize {164 pub const fn len_with_nul(&self) -> usize {
165 // SAFETY: This is one of the invariant of `CStr`.
166 // We add a `unreachable_unchecked` here to hint the optimizer that
167 // the value returned from this function is non-zero.
168 if self.0.is_empty() {165 if self.0.is_empty() {
166 // SAFETY: This is one of the invariant of `CStr`.
167 // We add a `unreachable_unchecked` here to hint the optimizer that
168 // the value returned from this function is non-zero.
169 unsafe { core::hint::unreachable_unchecked() };169 unsafe { core::hint::unreachable_unchecked() };
170 }170 }
171 self.0.len()171 self.0.len()
@@ -301,6 +301,7 @@ impl CStr { · 129 unmodified lines
301 /// ```301 /// ```
302 #[inline]302 #[inline]
303 pub unsafe fn as_str_unchecked(&self) -> &str {303 pub unsafe fn as_str_unchecked(&self) -> &str {
304 // SAFETY: TODO.
304 unsafe { core::str::from_utf8_unchecked(self.as_bytes()) }305 unsafe { core::str::from_utf8_unchecked(self.as_bytes()) }
305 }306 }
306 307
rust/kernel/sync/condvar.rs+1−1
@@ -92,8 +92,8 @@ pub struct CondVar { · 91 unmodified lines
92 _pin: PhantomPinned,92 _pin: PhantomPinned,
93}93}
94 94
95// SAFETY: `CondVar` only uses a `struct wait_queue_head`, which is safe to use on any thread.
96#[allow(clippy::non_send_fields_in_send_ty)]95#[allow(clippy::non_send_fields_in_send_ty)]
96// SAFETY: `CondVar` only uses a `struct wait_queue_head`, which is safe to use on any thread.
97unsafe impl Send for CondVar {}97unsafe impl Send for CondVar {}
98 98
99// SAFETY: `CondVar` only uses a `struct wait_queue_head`, which is safe to use on multiple threads99// SAFETY: `CondVar` only uses a `struct wait_queue_head`, which is safe to use on multiple threads
rust/kernel/sync/lock.rs+3−3
@@ -150,9 +150,9 @@ impl<T: ?Sized, B: Backend> Guard<'_, T, B> { · 149 unmodified lines
150 // SAFETY: The caller owns the lock, so it is safe to unlock it.150 // SAFETY: The caller owns the lock, so it is safe to unlock it.
151 unsafe { B::unlock(self.lock.state.get(), &self.state) };151 unsafe { B::unlock(self.lock.state.get(), &self.state) };
152 152
153 // SAFETY: The lock was just unlocked above and is being relocked now.153 let _relock = ScopeGuard::new(||
154 let _relock =154 // SAFETY: The lock was just unlocked above and is being relocked now.
155 ScopeGuard::new(|| unsafe { B::relock(self.lock.state.get(), &mut self.state) });155 unsafe { B::relock(self.lock.state.get(), &mut self.state) });
156 156
157 cb()157 cb()
158 }158 }
rust/kernel/types.rs+4−0
@@ -410,6 +410,7 @@ impl<T: AlwaysRefCounted> ARef<T> { · 409 unmodified lines
410 ///410 ///
411 /// struct Empty {}411 /// struct Empty {}
412 ///412 ///
413 /// # // SAFETY: TODO.
413 /// unsafe impl AlwaysRefCounted for Empty {414 /// unsafe impl AlwaysRefCounted for Empty {
414 /// fn inc_ref(&self) {}415 /// fn inc_ref(&self) {}
415 /// unsafe fn dec_ref(_obj: NonNull<Self>) {}416 /// unsafe fn dec_ref(_obj: NonNull<Self>) {}
@@ -417,6 +418,7 @@ impl<T: AlwaysRefCounted> ARef<T> { · 1 unmodified line
417 ///418 ///
418 /// let mut data = Empty {};419 /// let mut data = Empty {};
419 /// let ptr = NonNull::<Empty>::new(&mut data as *mut _).unwrap();420 /// let ptr = NonNull::<Empty>::new(&mut data as *mut _).unwrap();
421 /// # // SAFETY: TODO.
420 /// let data_ref: ARef<Empty> = unsafe { ARef::from_raw(ptr) };422 /// let data_ref: ARef<Empty> = unsafe { ARef::from_raw(ptr) };
421 /// let raw_ptr: NonNull<Empty> = ARef::into_raw(data_ref);423 /// let raw_ptr: NonNull<Empty> = ARef::into_raw(data_ref);
422 ///424 ///
@@ -492,6 +494,7 @@ pub unsafe trait FromBytes {} · 69 unmodified lines
492 494
493macro_rules! impl_frombytes {495macro_rules! impl_frombytes {
494 ($($({$($generics:tt)*})? $t:ty, )*) => {496 ($($({$($generics:tt)*})? $t:ty, )*) => {
497 // SAFETY: Safety comments written in the macro invocation.
495 $(unsafe impl$($($generics)*)? FromBytes for $t {})*498 $(unsafe impl$($($generics)*)? FromBytes for $t {})*
496 };499 };
497}500}
@@ -526,6 +529,7 @@ pub unsafe trait AsBytes {} · 28 unmodified lines
526 529
527macro_rules! impl_asbytes {530macro_rules! impl_asbytes {
528 ($($({$($generics:tt)*})? $t:ty, )*) => {531 ($($({$($generics:tt)*})? $t:ty, )*) => {
532 // SAFETY: Safety comments written in the macro invocation.
529 $(unsafe impl$($($generics)*)? AsBytes for $t {})*533 $(unsafe impl$($($generics)*)? AsBytes for $t {})*
530 };534 };
531}535}
rust/kernel/workqueue.rs+4−0
@@ -519,6 +519,7 @@ impl_has_work! { · 518 unmodified lines
519 impl{T} HasWork<Self> for ClosureWork<T> { self.work }519 impl{T} HasWork<Self> for ClosureWork<T> { self.work }
520}520}
521 521
522// SAFETY: TODO.
522unsafe impl<T, const ID: u64> WorkItemPointer<ID> for Arc<T>523unsafe impl<T, const ID: u64> WorkItemPointer<ID> for Arc<T>
523where524where
524 T: WorkItem<ID, Pointer = Self>,525 T: WorkItem<ID, Pointer = Self>,
@@ -536,6 +537,7 @@ where · 11 unmodified lines
536 }537 }
537}538}
538 539
540// SAFETY: TODO.
539unsafe impl<T, const ID: u64> RawWorkItem<ID> for Arc<T>541unsafe impl<T, const ID: u64> RawWorkItem<ID> for Arc<T>
540where542where
541 T: WorkItem<ID, Pointer = Self>,543 T: WorkItem<ID, Pointer = Self>,
@@ -564,6 +566,7 @@ where · 22 unmodified lines
564 }566 }
565}567}
566 568
569// SAFETY: TODO.
567unsafe impl<T, const ID: u64> WorkItemPointer<ID> for Pin<Box<T>>570unsafe impl<T, const ID: u64> WorkItemPointer<ID> for Pin<Box<T>>
568where571where
569 T: WorkItem<ID, Pointer = Self>,572 T: WorkItem<ID, Pointer = Self>,
@@ -583,6 +586,7 @@ where · 13 unmodified lines
583 }586 }
584}587}
585 588
589// SAFETY: TODO.
586unsafe impl<T, const ID: u64> RawWorkItem<ID> for Pin<Box<T>>590unsafe impl<T, const ID: u64> RawWorkItem<ID> for Pin<Box<T>>
587where591where
588 T: WorkItem<ID, Pointer = Self>,592 T: WorkItem<ID, Pointer = Self>,
rust/uapi/lib.rs+1−0
@@ -14,6 +14,7 @@ · 13 unmodified lines
14#![cfg_attr(test, allow(unsafe_op_in_unsafe_fn))]14#![cfg_attr(test, allow(unsafe_op_in_unsafe_fn))]
15#![allow(15#![allow(
16 clippy::all,16 clippy::all,
17 clippy::undocumented_unsafe_blocks,
17 dead_code,18 dead_code,
18 missing_docs,19 missing_docs,
19 non_camel_case_types,20 non_camel_case_types,