mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-17 02:15:57 +00:00
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. Link: https://github.com/Rust-for-Linux/linux/issues/351 [1] Link: https://rust-lang.github.io/rust-clippy/master/#/undocumented_unsafe_blocks [2] Link: https://github.com/rust-lang/rust-clippy/issues/13189 [3] Reviewed-by: Alice Ryhl <aliceryhl@google.com> Reviewed-by: Trevor Gross <tmgross@umich.edu> Tested-by: Gary Guo <gary@garyguo.net> Reviewed-by: Gary Guo <gary@garyguo.net> Link: https://lore.kernel.org/r/20240904204347.168520-5-ojeda@kernel.org Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
This commit is contained in:
parent
567cdff53e
commit
db4f72c904
1
Makefile
1
Makefile
@ -457,6 +457,7 @@ export rust_common_flags := --edition=2021 \
|
|||||||
-Wclippy::needless_bitwise_bool \
|
-Wclippy::needless_bitwise_bool \
|
||||||
-Wclippy::needless_continue \
|
-Wclippy::needless_continue \
|
||||||
-Wclippy::no_mangle_with_rust_abi \
|
-Wclippy::no_mangle_with_rust_abi \
|
||||||
|
-Wclippy::undocumented_unsafe_blocks \
|
||||||
-Wrustdoc::missing_crate_level_docs
|
-Wrustdoc::missing_crate_level_docs
|
||||||
|
|
||||||
KBUILD_HOSTCFLAGS := $(KBUILD_USERHOSTCFLAGS) $(HOST_LFS_CFLAGS) \
|
KBUILD_HOSTCFLAGS := $(KBUILD_USERHOSTCFLAGS) $(HOST_LFS_CFLAGS) \
|
||||||
|
@ -17,5 +17,6 @@ pub extern "C" fn kasan_test_rust_uaf() -> u8 {
|
|||||||
}
|
}
|
||||||
let ptr: *mut u8 = addr_of_mut!(v[2048]);
|
let ptr: *mut u8 = addr_of_mut!(v[2048]);
|
||||||
drop(v);
|
drop(v);
|
||||||
|
// SAFETY: Incorrect, on purpose.
|
||||||
unsafe { *ptr }
|
unsafe { *ptr }
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
)]
|
)]
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
|
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||||
mod bindings_raw {
|
mod bindings_raw {
|
||||||
// Use glob import here to expose all helpers.
|
// Use glob import here to expose all helpers.
|
||||||
// Symbols defined within the module will take precedence to the glob import.
|
// 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
|
|||||||
unsafe { bindings::krealloc(ptr as *const core::ffi::c_void, size, flags.0) as *mut u8 }
|
unsafe { bindings::krealloc(ptr as *const core::ffi::c_void, size, flags.0) as *mut u8 }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SAFETY: TODO.
|
||||||
unsafe impl GlobalAlloc for KernelAllocator {
|
unsafe impl GlobalAlloc for KernelAllocator {
|
||||||
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
|
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
|
||||||
// SAFETY: `ptr::null_mut()` is null and `layout` has a non-zero size by the function safety
|
// 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 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) {
|
unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) {
|
||||||
|
// SAFETY: TODO.
|
||||||
unsafe {
|
unsafe {
|
||||||
bindings::kfree(ptr as *const core::ffi::c_void);
|
bindings::kfree(ptr as *const core::ffi::c_void);
|
||||||
}
|
}
|
||||||
|
@ -171,9 +171,11 @@ impl fmt::Debug for Error {
|
|||||||
match self.name() {
|
match self.name() {
|
||||||
// Print out number if no name can be found.
|
// Print out number if no name can be found.
|
||||||
None => f.debug_tuple("Error").field(&-self.0).finish(),
|
None => f.debug_tuple("Error").field(&-self.0).finish(),
|
||||||
// SAFETY: These strings are ASCII-only.
|
|
||||||
Some(name) => f
|
Some(name) => f
|
||||||
.debug_tuple(unsafe { core::str::from_utf8_unchecked(name) })
|
.debug_tuple(
|
||||||
|
// SAFETY: These strings are ASCII-only.
|
||||||
|
unsafe { core::str::from_utf8_unchecked(name) },
|
||||||
|
)
|
||||||
.finish(),
|
.finish(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -277,6 +279,8 @@ pub(crate) fn from_err_ptr<T>(ptr: *mut T) -> Result<*mut T> {
|
|||||||
if unsafe { bindings::IS_ERR(const_ptr) } {
|
if unsafe { bindings::IS_ERR(const_ptr) } {
|
||||||
// SAFETY: The FFI function does not deref the pointer.
|
// SAFETY: The FFI function does not deref the pointer.
|
||||||
let err = unsafe { bindings::PTR_ERR(const_ptr) };
|
let err = unsafe { bindings::PTR_ERR(const_ptr) };
|
||||||
|
|
||||||
|
#[allow(clippy::unnecessary_cast)]
|
||||||
// CAST: If `IS_ERR()` returns `true`,
|
// CAST: If `IS_ERR()` returns `true`,
|
||||||
// then `PTR_ERR()` is guaranteed to return a
|
// then `PTR_ERR()` is guaranteed to return a
|
||||||
// negative value greater-or-equal to `-bindings::MAX_ERRNO`,
|
// 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> {
|
|||||||
//
|
//
|
||||||
// SAFETY: `IS_ERR()` ensures `err` is a
|
// SAFETY: `IS_ERR()` ensures `err` is a
|
||||||
// negative value greater-or-equal to `-bindings::MAX_ERRNO`.
|
// negative value greater-or-equal to `-bindings::MAX_ERRNO`.
|
||||||
#[allow(clippy::unnecessary_cast)]
|
|
||||||
return Err(unsafe { Error::from_errno_unchecked(err as core::ffi::c_int) });
|
return Err(unsafe { Error::from_errno_unchecked(err as core::ffi::c_int) });
|
||||||
}
|
}
|
||||||
Ok(ptr)
|
Ok(ptr)
|
||||||
|
@ -541,6 +541,7 @@ macro_rules! stack_try_pin_init {
|
|||||||
/// }
|
/// }
|
||||||
/// pin_init!(&this in Buf {
|
/// pin_init!(&this in Buf {
|
||||||
/// buf: [0; 64],
|
/// buf: [0; 64],
|
||||||
|
/// // SAFETY: TODO.
|
||||||
/// ptr: unsafe { addr_of_mut!((*this.as_ptr()).buf).cast() },
|
/// ptr: unsafe { addr_of_mut!((*this.as_ptr()).buf).cast() },
|
||||||
/// pin: PhantomPinned,
|
/// pin: PhantomPinned,
|
||||||
/// });
|
/// });
|
||||||
@ -875,6 +876,7 @@ pub unsafe trait PinInit<T: ?Sized, E = Infallible>: Sized {
|
|||||||
/// }
|
/// }
|
||||||
///
|
///
|
||||||
/// let foo = pin_init!(Foo {
|
/// let foo = pin_init!(Foo {
|
||||||
|
/// // SAFETY: TODO.
|
||||||
/// raw <- unsafe {
|
/// raw <- unsafe {
|
||||||
/// Opaque::ffi_init(|s| {
|
/// Opaque::ffi_init(|s| {
|
||||||
/// init_foo(s);
|
/// init_foo(s);
|
||||||
@ -1162,6 +1164,7 @@ where
|
|||||||
// SAFETY: Every type can be initialized by-value.
|
// SAFETY: Every type can be initialized by-value.
|
||||||
unsafe impl<T, E> Init<T, E> for T {
|
unsafe impl<T, E> Init<T, E> for T {
|
||||||
unsafe fn __init(self, slot: *mut T) -> Result<(), E> {
|
unsafe fn __init(self, slot: *mut T) -> Result<(), E> {
|
||||||
|
// SAFETY: TODO.
|
||||||
unsafe { slot.write(self) };
|
unsafe { slot.write(self) };
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -1170,6 +1173,7 @@ unsafe impl<T, E> Init<T, E> for T {
|
|||||||
// SAFETY: Every type can be initialized by-value. `__pinned_init` calls `__init`.
|
// SAFETY: Every type can be initialized by-value. `__pinned_init` calls `__init`.
|
||||||
unsafe impl<T, E> PinInit<T, E> for T {
|
unsafe impl<T, E> PinInit<T, E> for T {
|
||||||
unsafe fn __pinned_init(self, slot: *mut T) -> Result<(), E> {
|
unsafe fn __pinned_init(self, slot: *mut T) -> Result<(), E> {
|
||||||
|
// SAFETY: TODO.
|
||||||
unsafe { self.__init(slot) }
|
unsafe { self.__init(slot) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1411,6 +1415,7 @@ pub fn zeroed<T: Zeroable>() -> impl Init<T> {
|
|||||||
|
|
||||||
macro_rules! impl_zeroable {
|
macro_rules! impl_zeroable {
|
||||||
($($({$($generics:tt)*})? $t:ty, )*) => {
|
($($({$($generics:tt)*})? $t:ty, )*) => {
|
||||||
|
// SAFETY: Safety comments written in the macro invocation.
|
||||||
$(unsafe impl$($($generics)*)? Zeroable for $t {})*
|
$(unsafe impl$($($generics)*)? Zeroable for $t {})*
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -112,10 +112,12 @@ impl<T: ?Sized> Clone for AllData<T> {
|
|||||||
|
|
||||||
impl<T: ?Sized> Copy for AllData<T> {}
|
impl<T: ?Sized> Copy for AllData<T> {}
|
||||||
|
|
||||||
|
// SAFETY: TODO.
|
||||||
unsafe impl<T: ?Sized> InitData for AllData<T> {
|
unsafe impl<T: ?Sized> InitData for AllData<T> {
|
||||||
type Datee = T;
|
type Datee = T;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SAFETY: TODO.
|
||||||
unsafe impl<T: ?Sized> HasInitData for T {
|
unsafe impl<T: ?Sized> HasInitData for T {
|
||||||
type InitData = AllData<T>;
|
type InitData = AllData<T>;
|
||||||
|
|
||||||
|
@ -513,6 +513,7 @@ macro_rules! __pinned_drop {
|
|||||||
}
|
}
|
||||||
),
|
),
|
||||||
) => {
|
) => {
|
||||||
|
// SAFETY: TODO.
|
||||||
unsafe $($impl_sig)* {
|
unsafe $($impl_sig)* {
|
||||||
// Inherit all attributes and the type/ident tokens for the signature.
|
// Inherit all attributes and the type/ident tokens for the signature.
|
||||||
$(#[$($attr)*])*
|
$(#[$($attr)*])*
|
||||||
@ -872,6 +873,7 @@ macro_rules! __pin_data {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SAFETY: TODO.
|
||||||
unsafe impl<$($impl_generics)*>
|
unsafe impl<$($impl_generics)*>
|
||||||
$crate::init::__internal::PinData for __ThePinData<$($ty_generics)*>
|
$crate::init::__internal::PinData for __ThePinData<$($ty_generics)*>
|
||||||
where $($whr)*
|
where $($whr)*
|
||||||
@ -997,6 +999,7 @@ macro_rules! __pin_data {
|
|||||||
slot: *mut $p_type,
|
slot: *mut $p_type,
|
||||||
init: impl $crate::init::PinInit<$p_type, E>,
|
init: impl $crate::init::PinInit<$p_type, E>,
|
||||||
) -> ::core::result::Result<(), E> {
|
) -> ::core::result::Result<(), E> {
|
||||||
|
// SAFETY: TODO.
|
||||||
unsafe { $crate::init::PinInit::__pinned_init(init, slot) }
|
unsafe { $crate::init::PinInit::__pinned_init(init, slot) }
|
||||||
}
|
}
|
||||||
)*
|
)*
|
||||||
@ -1007,6 +1010,7 @@ macro_rules! __pin_data {
|
|||||||
slot: *mut $type,
|
slot: *mut $type,
|
||||||
init: impl $crate::init::Init<$type, E>,
|
init: impl $crate::init::Init<$type, E>,
|
||||||
) -> ::core::result::Result<(), E> {
|
) -> ::core::result::Result<(), E> {
|
||||||
|
// SAFETY: TODO.
|
||||||
unsafe { $crate::init::Init::__init(init, slot) }
|
unsafe { $crate::init::Init::__init(init, slot) }
|
||||||
}
|
}
|
||||||
)*
|
)*
|
||||||
@ -1121,6 +1125,8 @@ macro_rules! __init_internal {
|
|||||||
// no possibility of returning without `unsafe`.
|
// no possibility of returning without `unsafe`.
|
||||||
struct __InitOk;
|
struct __InitOk;
|
||||||
// Get the data about fields from the supplied type.
|
// Get the data about fields from the supplied type.
|
||||||
|
//
|
||||||
|
// SAFETY: TODO.
|
||||||
let data = unsafe {
|
let data = unsafe {
|
||||||
use $crate::init::__internal::$has_data;
|
use $crate::init::__internal::$has_data;
|
||||||
// Here we abuse `paste!` to retokenize `$t`. Declarative macros have some internal
|
// Here we abuse `paste!` to retokenize `$t`. Declarative macros have some internal
|
||||||
@ -1176,6 +1182,7 @@ macro_rules! __init_internal {
|
|||||||
let init = move |slot| -> ::core::result::Result<(), $err> {
|
let init = move |slot| -> ::core::result::Result<(), $err> {
|
||||||
init(slot).map(|__InitOk| ())
|
init(slot).map(|__InitOk| ())
|
||||||
};
|
};
|
||||||
|
// SAFETY: TODO.
|
||||||
let init = unsafe { $crate::init::$construct_closure::<_, $err>(init) };
|
let init = unsafe { $crate::init::$construct_closure::<_, $err>(init) };
|
||||||
init
|
init
|
||||||
}};
|
}};
|
||||||
@ -1324,6 +1331,8 @@ macro_rules! __init_internal {
|
|||||||
// Endpoint, nothing more to munch, create the initializer.
|
// Endpoint, nothing more to munch, create the initializer.
|
||||||
// Since we are in the closure that is never called, this will never get executed.
|
// Since we are in the closure that is never called, this will never get executed.
|
||||||
// We abuse `slot` to get the correct type inference here:
|
// We abuse `slot` to get the correct type inference here:
|
||||||
|
//
|
||||||
|
// SAFETY: TODO.
|
||||||
unsafe {
|
unsafe {
|
||||||
// Here we abuse `paste!` to retokenize `$t`. Declarative macros have some internal
|
// Here we abuse `paste!` to retokenize `$t`. Declarative macros have some internal
|
||||||
// information that is associated to already parsed fragments, so a path fragment
|
// 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> {
|
|||||||
///
|
///
|
||||||
/// `item` must not be in a different linked list (with the same id).
|
/// `item` must not be in a different linked list (with the same id).
|
||||||
pub unsafe fn remove(&mut self, item: &T) -> Option<ListArc<T, ID>> {
|
pub unsafe fn remove(&mut self, item: &T) -> Option<ListArc<T, ID>> {
|
||||||
|
// SAFETY: TODO.
|
||||||
let mut item = unsafe { ListLinks::fields(T::view_links(item)) };
|
let mut item = unsafe { ListLinks::fields(T::view_links(item)) };
|
||||||
// SAFETY: The user provided a reference, and reference are never dangling.
|
// SAFETY: The user provided a reference, and reference are never dangling.
|
||||||
//
|
//
|
||||||
|
@ -23,6 +23,7 @@ unsafe extern "C" fn rust_fmt_argument(
|
|||||||
use fmt::Write;
|
use fmt::Write;
|
||||||
// SAFETY: The C contract guarantees that `buf` is valid if it's less than `end`.
|
// SAFETY: The C contract guarantees that `buf` is valid if it's less than `end`.
|
||||||
let mut w = unsafe { RawFormatter::from_ptrs(buf.cast(), end.cast()) };
|
let mut w = unsafe { RawFormatter::from_ptrs(buf.cast(), end.cast()) };
|
||||||
|
// SAFETY: TODO.
|
||||||
let _ = w.write_fmt(unsafe { *(ptr as *const fmt::Arguments<'_>) });
|
let _ = w.write_fmt(unsafe { *(ptr as *const fmt::Arguments<'_>) });
|
||||||
w.pos().cast()
|
w.pos().cast()
|
||||||
}
|
}
|
||||||
@ -102,6 +103,7 @@ pub unsafe fn call_printk(
|
|||||||
) {
|
) {
|
||||||
// `_printk` does not seem to fail in any path.
|
// `_printk` does not seem to fail in any path.
|
||||||
#[cfg(CONFIG_PRINTK)]
|
#[cfg(CONFIG_PRINTK)]
|
||||||
|
// SAFETY: TODO.
|
||||||
unsafe {
|
unsafe {
|
||||||
bindings::_printk(
|
bindings::_printk(
|
||||||
format_string.as_ptr() as _,
|
format_string.as_ptr() as _,
|
||||||
|
@ -162,10 +162,10 @@ impl CStr {
|
|||||||
/// Returns the length of this string with `NUL`.
|
/// Returns the length of this string with `NUL`.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const fn len_with_nul(&self) -> usize {
|
pub const fn len_with_nul(&self) -> usize {
|
||||||
// SAFETY: This is one of the invariant of `CStr`.
|
|
||||||
// We add a `unreachable_unchecked` here to hint the optimizer that
|
|
||||||
// the value returned from this function is non-zero.
|
|
||||||
if self.0.is_empty() {
|
if self.0.is_empty() {
|
||||||
|
// SAFETY: This is one of the invariant of `CStr`.
|
||||||
|
// We add a `unreachable_unchecked` here to hint the optimizer that
|
||||||
|
// the value returned from this function is non-zero.
|
||||||
unsafe { core::hint::unreachable_unchecked() };
|
unsafe { core::hint::unreachable_unchecked() };
|
||||||
}
|
}
|
||||||
self.0.len()
|
self.0.len()
|
||||||
@ -301,6 +301,7 @@ impl CStr {
|
|||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn as_str_unchecked(&self) -> &str {
|
pub unsafe fn as_str_unchecked(&self) -> &str {
|
||||||
|
// SAFETY: TODO.
|
||||||
unsafe { core::str::from_utf8_unchecked(self.as_bytes()) }
|
unsafe { core::str::from_utf8_unchecked(self.as_bytes()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,8 +92,8 @@ pub struct CondVar {
|
|||||||
_pin: PhantomPinned,
|
_pin: PhantomPinned,
|
||||||
}
|
}
|
||||||
|
|
||||||
// SAFETY: `CondVar` only uses a `struct wait_queue_head`, which is safe to use on any thread.
|
|
||||||
#[allow(clippy::non_send_fields_in_send_ty)]
|
#[allow(clippy::non_send_fields_in_send_ty)]
|
||||||
|
// SAFETY: `CondVar` only uses a `struct wait_queue_head`, which is safe to use on any thread.
|
||||||
unsafe impl Send for CondVar {}
|
unsafe impl Send for CondVar {}
|
||||||
|
|
||||||
// SAFETY: `CondVar` only uses a `struct wait_queue_head`, which is safe to use on multiple threads
|
// 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> {
|
|||||||
// SAFETY: The caller owns the lock, so it is safe to unlock it.
|
// SAFETY: The caller owns the lock, so it is safe to unlock it.
|
||||||
unsafe { B::unlock(self.lock.state.get(), &self.state) };
|
unsafe { B::unlock(self.lock.state.get(), &self.state) };
|
||||||
|
|
||||||
// SAFETY: The lock was just unlocked above and is being relocked now.
|
let _relock = ScopeGuard::new(||
|
||||||
let _relock =
|
// SAFETY: The lock was just unlocked above and is being relocked now.
|
||||||
ScopeGuard::new(|| unsafe { B::relock(self.lock.state.get(), &mut self.state) });
|
unsafe { B::relock(self.lock.state.get(), &mut self.state) });
|
||||||
|
|
||||||
cb()
|
cb()
|
||||||
}
|
}
|
||||||
|
@ -410,6 +410,7 @@ impl<T: AlwaysRefCounted> ARef<T> {
|
|||||||
///
|
///
|
||||||
/// struct Empty {}
|
/// struct Empty {}
|
||||||
///
|
///
|
||||||
|
/// # // SAFETY: TODO.
|
||||||
/// unsafe impl AlwaysRefCounted for Empty {
|
/// unsafe impl AlwaysRefCounted for Empty {
|
||||||
/// fn inc_ref(&self) {}
|
/// fn inc_ref(&self) {}
|
||||||
/// unsafe fn dec_ref(_obj: NonNull<Self>) {}
|
/// unsafe fn dec_ref(_obj: NonNull<Self>) {}
|
||||||
@ -417,6 +418,7 @@ impl<T: AlwaysRefCounted> ARef<T> {
|
|||||||
///
|
///
|
||||||
/// let mut data = Empty {};
|
/// let mut data = Empty {};
|
||||||
/// let ptr = NonNull::<Empty>::new(&mut data as *mut _).unwrap();
|
/// let ptr = NonNull::<Empty>::new(&mut data as *mut _).unwrap();
|
||||||
|
/// # // SAFETY: TODO.
|
||||||
/// let data_ref: ARef<Empty> = unsafe { ARef::from_raw(ptr) };
|
/// let data_ref: ARef<Empty> = unsafe { ARef::from_raw(ptr) };
|
||||||
/// let raw_ptr: NonNull<Empty> = ARef::into_raw(data_ref);
|
/// let raw_ptr: NonNull<Empty> = ARef::into_raw(data_ref);
|
||||||
///
|
///
|
||||||
@ -492,6 +494,7 @@ pub unsafe trait FromBytes {}
|
|||||||
|
|
||||||
macro_rules! impl_frombytes {
|
macro_rules! impl_frombytes {
|
||||||
($($({$($generics:tt)*})? $t:ty, )*) => {
|
($($({$($generics:tt)*})? $t:ty, )*) => {
|
||||||
|
// SAFETY: Safety comments written in the macro invocation.
|
||||||
$(unsafe impl$($($generics)*)? FromBytes for $t {})*
|
$(unsafe impl$($($generics)*)? FromBytes for $t {})*
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -526,6 +529,7 @@ pub unsafe trait AsBytes {}
|
|||||||
|
|
||||||
macro_rules! impl_asbytes {
|
macro_rules! impl_asbytes {
|
||||||
($($({$($generics:tt)*})? $t:ty, )*) => {
|
($($({$($generics:tt)*})? $t:ty, )*) => {
|
||||||
|
// SAFETY: Safety comments written in the macro invocation.
|
||||||
$(unsafe impl$($($generics)*)? AsBytes for $t {})*
|
$(unsafe impl$($($generics)*)? AsBytes for $t {})*
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -519,6 +519,7 @@ impl_has_work! {
|
|||||||
impl{T} HasWork<Self> for ClosureWork<T> { self.work }
|
impl{T} HasWork<Self> for ClosureWork<T> { self.work }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SAFETY: TODO.
|
||||||
unsafe impl<T, const ID: u64> WorkItemPointer<ID> for Arc<T>
|
unsafe impl<T, const ID: u64> WorkItemPointer<ID> for Arc<T>
|
||||||
where
|
where
|
||||||
T: WorkItem<ID, Pointer = Self>,
|
T: WorkItem<ID, Pointer = Self>,
|
||||||
@ -536,6 +537,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SAFETY: TODO.
|
||||||
unsafe impl<T, const ID: u64> RawWorkItem<ID> for Arc<T>
|
unsafe impl<T, const ID: u64> RawWorkItem<ID> for Arc<T>
|
||||||
where
|
where
|
||||||
T: WorkItem<ID, Pointer = Self>,
|
T: WorkItem<ID, Pointer = Self>,
|
||||||
@ -564,6 +566,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SAFETY: TODO.
|
||||||
unsafe impl<T, const ID: u64> WorkItemPointer<ID> for Pin<Box<T>>
|
unsafe impl<T, const ID: u64> WorkItemPointer<ID> for Pin<Box<T>>
|
||||||
where
|
where
|
||||||
T: WorkItem<ID, Pointer = Self>,
|
T: WorkItem<ID, Pointer = Self>,
|
||||||
@ -583,6 +586,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SAFETY: TODO.
|
||||||
unsafe impl<T, const ID: u64> RawWorkItem<ID> for Pin<Box<T>>
|
unsafe impl<T, const ID: u64> RawWorkItem<ID> for Pin<Box<T>>
|
||||||
where
|
where
|
||||||
T: WorkItem<ID, Pointer = Self>,
|
T: WorkItem<ID, Pointer = Self>,
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#![cfg_attr(test, allow(unsafe_op_in_unsafe_fn))]
|
#![cfg_attr(test, allow(unsafe_op_in_unsafe_fn))]
|
||||||
#![allow(
|
#![allow(
|
||||||
clippy::all,
|
clippy::all,
|
||||||
|
clippy::undocumented_unsafe_blocks,
|
||||||
dead_code,
|
dead_code,
|
||||||
missing_docs,
|
missing_docs,
|
||||||
non_camel_case_types,
|
non_camel_case_types,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user