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.
Unified · Split
| @@ -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_docs | 461 | -Wrustdoc::missing_crate_level_docs |
| 461 | 462 | ||
| 462 | KBUILD_HOSTCFLAGS := $(KBUILD_USERHOSTCFLAGS) $(HOST_LFS_CFLAGS) \ | 463 | KBUILD_HOSTCFLAGS := $(KBUILD_USERHOSTCFLAGS) $(HOST_LFS_CFLAGS) \ |
| @@ -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 | } |
| @@ -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)] | ||
| 28 | mod bindings_raw { | 29 | mod 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. |
| @@ -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. | ||
| 34 | unsafe impl GlobalAlloc for KernelAllocator { | 35 | unsafe 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 safety | 37 | // 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 | } |
| @@ -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) => f | 174 | 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 a | 285 | // 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 a | 291 | // 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) |
| @@ -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. |
| 1163 | unsafe impl<T, E> Init<T, E> for T { | 1165 | unsafe 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`. |
| 1171 | unsafe impl<T, E> PinInit<T, E> for T { | 1174 | unsafe 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 | ||
| 1412 | macro_rules! impl_zeroable { | 1416 | macro_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 | } |
| @@ -112,10 +112,12 @@ impl<T: ?Sized> Clone for AllData<T> { · 111 unmodified lines | |||
| 112 | 112 | ||
| 113 | impl<T: ?Sized> Copy for AllData<T> {} | 113 | impl<T: ?Sized> Copy for AllData<T> {} |
| 114 | 114 | ||
| 115 | // SAFETY: TODO. | ||
| 115 | unsafe impl<T: ?Sized> InitData for AllData<T> { | 116 | unsafe impl<T: ?Sized> InitData for AllData<T> { |
| 116 | type Datee = T; | 117 | type Datee = T; |
| 117 | } | 118 | } |
| 118 | 119 | ||
| 120 | // SAFETY: TODO. | ||
| 119 | unsafe impl<T: ?Sized> HasInitData for T { | 121 | unsafe impl<T: ?Sized> HasInitData for T { |
| 120 | type InitData = AllData<T>; | 122 | type InitData = AllData<T>; |
| 121 | 123 | ||
| @@ -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 internal | 1132 | // 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 | init | 1187 | 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 internal | 1337 | // Here we abuse `paste!` to retokenize `$t`. Declarative macros have some internal |
| 1329 | // information that is associated to already parsed fragments, so a path fragment | 1338 | // information that is associated to already parsed fragments, so a path fragment |
| @@ -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 | // |
| @@ -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 _, |
| @@ -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 | ||
| @@ -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. | ||
| 97 | unsafe impl Send for CondVar {} | 97 | unsafe impl Send for CondVar {} |
| 98 | 98 | ||
| 99 | // SAFETY: `CondVar` only uses a `struct wait_queue_head`, which is safe to use on multiple threads | 99 | // SAFETY: `CondVar` only uses a `struct wait_queue_head`, which is safe to use on multiple threads |
| @@ -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 | } |
| @@ -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 | ||
| 493 | macro_rules! impl_frombytes { | 495 | macro_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 | ||
| 527 | macro_rules! impl_asbytes { | 530 | macro_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 | } |
| @@ -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. | ||
| 522 | unsafe impl<T, const ID: u64> WorkItemPointer<ID> for Arc<T> | 523 | unsafe impl<T, const ID: u64> WorkItemPointer<ID> for Arc<T> |
| 523 | where | 524 | where |
| 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. | ||
| 539 | unsafe impl<T, const ID: u64> RawWorkItem<ID> for Arc<T> | 541 | unsafe impl<T, const ID: u64> RawWorkItem<ID> for Arc<T> |
| 540 | where | 542 | where |
| 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. | ||
| 567 | unsafe impl<T, const ID: u64> WorkItemPointer<ID> for Pin<Box<T>> | 570 | unsafe impl<T, const ID: u64> WorkItemPointer<ID> for Pin<Box<T>> |
| 568 | where | 571 | where |
| 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. | ||
| 586 | unsafe impl<T, const ID: u64> RawWorkItem<ID> for Pin<Box<T>> | 590 | unsafe impl<T, const ID: u64> RawWorkItem<ID> for Pin<Box<T>> |
| 587 | where | 591 | where |
| 588 | T: WorkItem<ID, Pointer = Self>, | 592 | T: WorkItem<ID, Pointer = Self>, |
| @@ -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, |