Skip to content

Commit 9409eaf

Browse files
committed
tokio enable the unsafe_op_in_unsafe_fn lint at the crate level
Signed-off-by: ADD-SP <[email protected]>
1 parent 5a709e3 commit 9409eaf

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+409
-149
lines changed

tokio/src/fs/file.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -917,7 +917,9 @@ impl std::os::unix::io::AsFd for File {
917917
#[cfg(unix)]
918918
impl std::os::unix::io::FromRawFd for File {
919919
unsafe fn from_raw_fd(fd: std::os::unix::io::RawFd) -> Self {
920-
StdFile::from_raw_fd(fd).into()
920+
// Safety: exactly the same safety contract as
921+
// `std::os::unix::io::FromRawFd::from_raw_fd`.
922+
unsafe { StdFile::from_raw_fd(fd).into() }
921923
}
922924
}
923925

@@ -942,7 +944,9 @@ cfg_windows! {
942944

943945
impl FromRawHandle for File {
944946
unsafe fn from_raw_handle(handle: RawHandle) -> Self {
945-
StdFile::from_raw_handle(handle).into()
947+
// Safety: exactly the same safety contract as
948+
// `FromRawHandle::from_raw_handle`.
949+
unsafe { StdFile::from_raw_handle(handle).into() }
946950
}
947951
}
948952
}

tokio/src/io/poll_evented.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,15 @@ feature! {
171171
loop {
172172
let evt = ready!(self.registration.poll_read_ready(cx))?;
173173

174-
let b = &mut *(buf.unfilled_mut() as *mut [std::mem::MaybeUninit<u8>] as *mut [u8]);
174+
// SAFETY:
175+
//
176+
// 1. `MaybeUninit<u8>` has the same memory layout as `u8`.
177+
// 2. `*mut [u8] as *mut [MaybeUninit<u8>]` follows the
178+
// [Pointer-to-pointer cast].
179+
//
180+
// [Pointer-to-pointer cast]:
181+
// https://doc.rust-lang.org/1.90.0/reference/expressions/operator-expr.html#r-expr.as.pointer
182+
let b = unsafe { &mut *(buf.unfilled_mut() as *mut [std::mem::MaybeUninit<u8>] as *mut [u8]) };
175183

176184
// used only when the cfgs below apply
177185
#[allow(unused_variables)]
@@ -213,7 +221,7 @@ feature! {
213221

214222
// Safety: We trust `TcpStream::read` to have filled up `n` bytes in the
215223
// buffer.
216-
buf.assume_init(n);
224+
unsafe { buf.assume_init(n) };
217225
buf.advance(n);
218226
return Poll::Ready(Ok(()));
219227
},

tokio/src/io/read_buf.rs

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,9 @@ unsafe impl<'a> bytes::BufMut for ReadBuf<'a> {
283283

284284
// SAFETY: The caller guarantees that at least `cnt` unfilled bytes have been initialized.
285285
unsafe fn advance_mut(&mut self, cnt: usize) {
286-
self.assume_init(cnt);
286+
unsafe {
287+
self.assume_init(cnt);
288+
}
287289
self.advance(cnt);
288290
}
289291

@@ -311,16 +313,49 @@ impl fmt::Debug for ReadBuf<'_> {
311313
}
312314
}
313315

316+
// TODO: This function looks very safe, consider remove the `unsafe` qualifier.
314317
unsafe fn slice_to_uninit_mut(slice: &mut [u8]) -> &mut [MaybeUninit<u8>] {
315-
&mut *(slice as *mut [u8] as *mut [MaybeUninit<u8>])
318+
// SAFETY:
319+
//
320+
// 1. `MaybeUninit<u8>` has the same memory layout as `u8`.
321+
// 2. `*mut [u8] as *mut [MaybeUninit<u8>]` follows the
322+
// [Pointer-to-pointer cast].
323+
//
324+
// [Pointer-to-pointer cast]:
325+
// https://doc.rust-lang.org/1.90.0/reference/expressions/operator-expr.html#r-expr.as.pointer
326+
unsafe { &mut *(slice as *mut [u8] as *mut [MaybeUninit<u8>]) }
316327
}
317328

329+
/// # Safety
330+
///
331+
/// The caller must ensure that `slice` is fully initialized.
318332
// TODO: This could use `MaybeUninit::slice_assume_init` when it is stable.
319333
unsafe fn slice_assume_init(slice: &[MaybeUninit<u8>]) -> &[u8] {
320-
&*(slice as *const [MaybeUninit<u8>] as *const [u8])
334+
// SAFETY:
335+
//
336+
// 1. `MaybeUninit<u8>` has the same memory layout as `u8`.
337+
// 2. `*const [MaybeUninit<u8>] as *const [u8]` follows the
338+
// [Pointer-to-pointer cast].
339+
// 3. The caller guarantees that `slice` is fully initialized.
340+
//
341+
// [Pointer-to-pointer cast]:
342+
// https://doc.rust-lang.org/1.90.0/reference/expressions/operator-expr.html#r-expr.as.pointer
343+
unsafe { &*(slice as *const [MaybeUninit<u8>] as *const [u8]) }
321344
}
322345

323346
// TODO: This could use `MaybeUninit::slice_assume_init_mut` when it is stable.
347+
/// # Safety
348+
///
349+
/// The caller must ensure that `slice` is fully initialized.
324350
unsafe fn slice_assume_init_mut(slice: &mut [MaybeUninit<u8>]) -> &mut [u8] {
325-
&mut *(slice as *mut [MaybeUninit<u8>] as *mut [u8])
351+
// SAFETY:
352+
//
353+
// 1. `MaybeUninit<u8>` has the same memory layout as `u8`.
354+
// 2. `*const [MaybeUninit<u8>] as *const [u8]` follows the
355+
// [Pointer-to-pointer cast].
356+
// 3. The caller guarantees that `slice` is fully initialized.
357+
//
358+
// [Pointer-to-pointer cast]:
359+
// https://doc.rust-lang.org/1.90.0/reference/expressions/operator-expr.html#r-expr.as.pointer
360+
unsafe { &mut *(slice as *mut [MaybeUninit<u8>] as *mut [u8]) }
326361
}

tokio/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
rust_2018_idioms,
1111
unreachable_pub
1212
)]
13-
#![deny(unused_must_use)]
13+
#![deny(unused_must_use, unsafe_op_in_unsafe_fn)]
1414
#![doc(test(
1515
no_crate_inject,
1616
attr(deny(warnings, rust_2018_idioms), allow(dead_code, unused_variables))

tokio/src/loom/std/atomic_u16.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ impl AtomicU16 {
2626
/// All mutations must have happened before the unsynchronized load.
2727
/// Additionally, there must be no concurrent mutations.
2828
pub(crate) unsafe fn unsync_load(&self) -> u16 {
29-
core::ptr::read(self.inner.get() as *const u16)
29+
unsafe { core::ptr::read(self.inner.get() as *const u16) }
3030
}
3131
}
3232

tokio/src/loom/std/atomic_u32.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ impl AtomicU32 {
2626
/// All mutations must have happened before the unsynchronized load.
2727
/// Additionally, there must be no concurrent mutations.
2828
pub(crate) unsafe fn unsync_load(&self) -> u32 {
29-
core::ptr::read(self.inner.get() as *const u32)
29+
unsafe { core::ptr::read(self.inner.get() as *const u32) }
3030
}
3131
}
3232

tokio/src/loom/std/atomic_usize.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ impl AtomicUsize {
2626
/// All mutations must have happened before the unsynchronized load.
2727
/// Additionally, there must be no concurrent mutations.
2828
pub(crate) unsafe fn unsync_load(&self) -> usize {
29-
core::ptr::read(self.inner.get() as *const usize)
29+
unsafe { core::ptr::read(self.inner.get() as *const usize) }
3030
}
3131

3232
pub(crate) fn with_mut<R>(&mut self, f: impl FnOnce(&mut usize) -> R) -> R {

tokio/src/macros/addr_of.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,16 @@ macro_rules! generate_addr_of_methods {
1111
)*}
1212
) => {
1313
impl<$($gen)*> $struct_name {$(
14+
#[doc = "# Safety"]
15+
#[doc = ""]
16+
#[doc = "The `self` pointer must be valid."]
1417
$(#[$attrs])*
1518
$vis unsafe fn $fn_name(me: ::core::ptr::NonNull<Self>) -> ::core::ptr::NonNull<$field_type> {
1619
let me = me.as_ptr();
17-
let field = ::std::ptr::addr_of_mut!((*me) $(.$field_name)+ );
18-
::core::ptr::NonNull::new_unchecked(field)
20+
// safety: the caller guarantees that `me` is valid
21+
let field = unsafe { ::std::ptr::addr_of_mut!((*me) $(.$field_name)+ ) };
22+
// safety: the field pointer is never null
23+
unsafe { ::core::ptr::NonNull::new_unchecked(field) }
1924
}
2025
)*}
2126
};

tokio/src/net/tcp/socket.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -836,7 +836,9 @@ cfg_unix! {
836836
/// The caller is responsible for ensuring that the socket is in
837837
/// non-blocking mode.
838838
unsafe fn from_raw_fd(fd: RawFd) -> TcpSocket {
839-
let inner = socket2::Socket::from_raw_fd(fd);
839+
// Safety: exactly the same safety requirements as the
840+
// `FromRawFd::from_raw_fd` trait method.
841+
let inner = unsafe { socket2::Socket::from_raw_fd(fd) };
840842
TcpSocket { inner }
841843
}
842844
}
@@ -875,7 +877,7 @@ cfg_windows! {
875877
/// The caller is responsible for ensuring that the socket is in
876878
/// non-blocking mode.
877879
unsafe fn from_raw_socket(socket: RawSocket) -> TcpSocket {
878-
let inner = socket2::Socket::from_raw_socket(socket);
880+
let inner = unsafe { socket2::Socket::from_raw_socket(socket) };
879881
TcpSocket { inner }
880882
}
881883
}

tokio/src/net/unix/socket.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,9 @@ impl AsFd for UnixSocket {
259259

260260
impl FromRawFd for UnixSocket {
261261
unsafe fn from_raw_fd(fd: RawFd) -> UnixSocket {
262-
let inner = socket2::Socket::from_raw_fd(fd);
262+
// Safety: exactly the same safety requirements as the
263+
// `FromRawFd::from_raw_fd` trait method.
264+
let inner = unsafe { socket2::Socket::from_raw_fd(fd) };
263265
UnixSocket { inner }
264266
}
265267
}

0 commit comments

Comments
 (0)