Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions tokio/src/fs/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -917,7 +917,9 @@ impl std::os::unix::io::AsFd for File {
#[cfg(unix)]
impl std::os::unix::io::FromRawFd for File {
unsafe fn from_raw_fd(fd: std::os::unix::io::RawFd) -> Self {
StdFile::from_raw_fd(fd).into()
// Safety: exactly the same safety contract as
// `std::os::unix::io::FromRawFd::from_raw_fd`.
unsafe { StdFile::from_raw_fd(fd).into() }
}
}

Expand All @@ -942,7 +944,9 @@ cfg_windows! {

impl FromRawHandle for File {
unsafe fn from_raw_handle(handle: RawHandle) -> Self {
StdFile::from_raw_handle(handle).into()
// Safety: exactly the same safety contract as
// `FromRawHandle::from_raw_handle`.
unsafe { StdFile::from_raw_handle(handle).into() }
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions tokio/src/io/poll_evented.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ feature! {
loop {
let evt = ready!(self.registration.poll_read_ready(cx))?;

let b = &mut *(buf.unfilled_mut() as *mut [std::mem::MaybeUninit<u8>] as *mut [u8]);
let b = unsafe { &mut *(buf.unfilled_mut() as *mut [std::mem::MaybeUninit<u8>] as *mut [u8]) };

// used only when the cfgs below apply
#[allow(unused_variables)]
Expand Down Expand Up @@ -213,7 +213,7 @@ feature! {

// Safety: We trust `TcpStream::read` to have filled up `n` bytes in the
// buffer.
buf.assume_init(n);
unsafe { buf.assume_init(n) };
buf.advance(n);
return Poll::Ready(Ok(()));
},
Expand Down
26 changes: 22 additions & 4 deletions tokio/src/io/read_buf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,9 @@ unsafe impl<'a> bytes::BufMut for ReadBuf<'a> {

// SAFETY: The caller guarantees that at least `cnt` unfilled bytes have been initialized.
unsafe fn advance_mut(&mut self, cnt: usize) {
self.assume_init(cnt);
unsafe {
self.assume_init(cnt);
}
Comment on lines +286 to +288
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function is very short, and it’s clear enough for developers to reason about the safety requirements, so we don’t need additional "Safety" comments here”

self.advance(cnt);
}

Expand Down Expand Up @@ -311,16 +313,32 @@ impl fmt::Debug for ReadBuf<'_> {
}
}

/// # Safety
///
/// The caller must ensure that `slice` is fully initialized
/// and never writes uninitialized bytes to the returned slice.
unsafe fn slice_to_uninit_mut(slice: &mut [u8]) -> &mut [MaybeUninit<u8>] {
&mut *(slice as *mut [u8] as *mut [MaybeUninit<u8>])
// SAFETY: `MaybeUninit<u8>` has the same memory layout as u8, and the caller
// promises to not write uninitialized bytes to the returned slice.
unsafe { &mut *(slice as *mut [u8] as *mut [MaybeUninit<u8>]) }
}

/// # Safety
///
/// The caller must ensure that `slice` is fully initialized.
// TODO: This could use `MaybeUninit::slice_assume_init` when it is stable.
unsafe fn slice_assume_init(slice: &[MaybeUninit<u8>]) -> &[u8] {
&*(slice as *const [MaybeUninit<u8>] as *const [u8])
// SAFETY: `MaybeUninit<u8>` has the same memory layout as u8, and the caller
// promises that `slice` is fully initialized.
unsafe { &*(slice as *const [MaybeUninit<u8>] as *const [u8]) }
}

/// # Safety
///
/// The caller must ensure that `slice` is fully initialized.
// TODO: This could use `MaybeUninit::slice_assume_init_mut` when it is stable.
unsafe fn slice_assume_init_mut(slice: &mut [MaybeUninit<u8>]) -> &mut [u8] {
&mut *(slice as *mut [MaybeUninit<u8>] as *mut [u8])
// SAFETY: `MaybeUninit<u8>` has the same memory layout as `u8`, and the caller
// promises that `slice` is fully initialized.
unsafe { &mut *(slice as *mut [MaybeUninit<u8>] as *mut [u8]) }
}
2 changes: 1 addition & 1 deletion tokio/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
rust_2018_idioms,
unreachable_pub
)]
#![deny(unused_must_use)]
#![deny(unused_must_use, unsafe_op_in_unsafe_fn)]
#![doc(test(
no_crate_inject,
attr(deny(warnings, rust_2018_idioms), allow(dead_code, unused_variables))
Expand Down
2 changes: 1 addition & 1 deletion tokio/src/loom/std/atomic_u16.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ impl AtomicU16 {
/// All mutations must have happened before the unsynchronized load.
/// Additionally, there must be no concurrent mutations.
pub(crate) unsafe fn unsync_load(&self) -> u16 {
core::ptr::read(self.inner.get() as *const u16)
unsafe { core::ptr::read(self.inner.get() as *const u16) }
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function is very short, and it’s clear enough for developers to reason about the safety requirements, so we don’t need additional "Safety" comments here”

}
}

Expand Down
2 changes: 1 addition & 1 deletion tokio/src/loom/std/atomic_u32.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ impl AtomicU32 {
/// All mutations must have happened before the unsynchronized load.
/// Additionally, there must be no concurrent mutations.
pub(crate) unsafe fn unsync_load(&self) -> u32 {
core::ptr::read(self.inner.get() as *const u32)
unsafe { core::ptr::read(self.inner.get() as *const u32) }
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function is very short, and it’s clear enough for developers to reason about the safety requirements, so we don’t need additional "Safety" comments here”

}
}

Expand Down
2 changes: 1 addition & 1 deletion tokio/src/loom/std/atomic_usize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ impl AtomicUsize {
/// All mutations must have happened before the unsynchronized load.
/// Additionally, there must be no concurrent mutations.
pub(crate) unsafe fn unsync_load(&self) -> usize {
core::ptr::read(self.inner.get() as *const usize)
unsafe { core::ptr::read(self.inner.get() as *const usize) }
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function is very short, and it’s clear enough for developers to reason about the safety requirements, so we don’t need additional "Safety" comments here”

}

pub(crate) fn with_mut<R>(&mut self, f: impl FnOnce(&mut usize) -> R) -> R {
Expand Down
9 changes: 7 additions & 2 deletions tokio/src/macros/addr_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,16 @@ macro_rules! generate_addr_of_methods {
)*}
) => {
impl<$($gen)*> $struct_name {$(
#[doc = "# Safety"]
#[doc = ""]
#[doc = "The `me` pointer must be valid."]
$(#[$attrs])*
$vis unsafe fn $fn_name(me: ::core::ptr::NonNull<Self>) -> ::core::ptr::NonNull<$field_type> {
let me = me.as_ptr();
let field = ::std::ptr::addr_of_mut!((*me) $(.$field_name)+ );
::core::ptr::NonNull::new_unchecked(field)
// safety: the caller guarantees that `me` is valid
let field = unsafe { ::std::ptr::addr_of_mut!((*me) $(.$field_name)+ ) };
// safety: the field pointer is never null
unsafe { ::core::ptr::NonNull::new_unchecked(field) }
}
)*}
};
Expand Down
6 changes: 4 additions & 2 deletions tokio/src/net/tcp/socket.rs
Original file line number Diff line number Diff line change
Expand Up @@ -836,7 +836,9 @@ cfg_unix! {
/// The caller is responsible for ensuring that the socket is in
/// non-blocking mode.
unsafe fn from_raw_fd(fd: RawFd) -> TcpSocket {
let inner = socket2::Socket::from_raw_fd(fd);
// Safety: exactly the same safety requirements as the
// `FromRawFd::from_raw_fd` trait method.
let inner = unsafe { socket2::Socket::from_raw_fd(fd) };
TcpSocket { inner }
}
}
Expand Down Expand Up @@ -875,7 +877,7 @@ cfg_windows! {
/// The caller is responsible for ensuring that the socket is in
/// non-blocking mode.
unsafe fn from_raw_socket(socket: RawSocket) -> TcpSocket {
let inner = socket2::Socket::from_raw_socket(socket);
let inner = unsafe { socket2::Socket::from_raw_socket(socket) };
TcpSocket { inner }
}
}
Expand Down
4 changes: 3 additions & 1 deletion tokio/src/net/unix/socket.rs
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,9 @@ impl AsFd for UnixSocket {

impl FromRawFd for UnixSocket {
unsafe fn from_raw_fd(fd: RawFd) -> UnixSocket {
let inner = socket2::Socket::from_raw_fd(fd);
// Safety: exactly the same safety requirements as the
// `FromRawFd::from_raw_fd` trait method.
let inner = unsafe { socket2::Socket::from_raw_fd(fd) };
UnixSocket { inner }
}
}
Expand Down
71 changes: 39 additions & 32 deletions tokio/src/net/windows/named_pipe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ impl NamedPipeServer {
/// [Tokio Runtime]: crate::runtime::Runtime
/// [enabled I/O]: crate::runtime::Builder::enable_io
pub unsafe fn from_raw_handle(handle: RawHandle) -> io::Result<Self> {
let named_pipe = mio_windows::NamedPipe::from_raw_handle(handle);
let named_pipe = unsafe { mio_windows::NamedPipe::from_raw_handle(handle) };

Ok(Self {
io: PollEvented::new(named_pipe)?,
Expand Down Expand Up @@ -999,7 +999,7 @@ impl NamedPipeClient {
/// [Tokio Runtime]: crate::runtime::Runtime
/// [enabled I/O]: crate::runtime::Builder::enable_io
pub unsafe fn from_raw_handle(handle: RawHandle) -> io::Result<Self> {
let named_pipe = mio_windows::NamedPipe::from_raw_handle(handle);
let named_pipe = unsafe { mio_windows::NamedPipe::from_raw_handle(handle) };

Ok(Self {
io: PollEvented::new(named_pipe)?,
Expand Down Expand Up @@ -2344,22 +2344,24 @@ impl ServerOptions {
mode
};

let h = windows_sys::CreateNamedPipeW(
addr.as_ptr(),
open_mode,
pipe_mode,
self.max_instances,
self.out_buffer_size,
self.in_buffer_size,
self.default_timeout,
attrs as *mut _,
);
let h = unsafe {
windows_sys::CreateNamedPipeW(
addr.as_ptr(),
open_mode,
pipe_mode,
self.max_instances,
self.out_buffer_size,
self.in_buffer_size,
self.default_timeout,
attrs as *mut _,
)
};

if h == windows_sys::INVALID_HANDLE_VALUE {
return Err(io::Error::last_os_error());
}

NamedPipeServer::from_raw_handle(h as _)
unsafe { NamedPipeServer::from_raw_handle(h as _) }
}
}

Expand Down Expand Up @@ -2550,31 +2552,34 @@ impl ClientOptions {
// we have access to windows_sys it ultimately doesn't hurt to use
// `CreateFile` explicitly since it allows the use of our already
// well-structured wide `addr` to pass into CreateFileW.
let h = windows_sys::CreateFileW(
addr.as_ptr(),
desired_access,
0,
attrs as *mut _,
windows_sys::OPEN_EXISTING,
self.get_flags(),
null_mut(),
);
let h = unsafe {
windows_sys::CreateFileW(
addr.as_ptr(),
desired_access,
0,
attrs as *mut _,
windows_sys::OPEN_EXISTING,
self.get_flags(),
null_mut(),
)
};

if h == windows_sys::INVALID_HANDLE_VALUE {
return Err(io::Error::last_os_error());
}

if matches!(self.pipe_mode, PipeMode::Message) {
let mode = windows_sys::PIPE_READMODE_MESSAGE;
let result =
windows_sys::SetNamedPipeHandleState(h, &mode, ptr::null_mut(), ptr::null_mut());
let result = unsafe {
windows_sys::SetNamedPipeHandleState(h, &mode, ptr::null_mut(), ptr::null_mut())
};

if result == 0 {
return Err(io::Error::last_os_error());
}
}

NamedPipeClient::from_raw_handle(h as _)
unsafe { NamedPipeClient::from_raw_handle(h as _) }
}

fn get_flags(&self) -> u32 {
Expand Down Expand Up @@ -2659,13 +2664,15 @@ unsafe fn named_pipe_info(handle: RawHandle) -> io::Result<PipeInfo> {
let mut in_buffer_size = 0;
let mut max_instances = 0;

let result = windows_sys::GetNamedPipeInfo(
handle as _,
&mut flags,
&mut out_buffer_size,
&mut in_buffer_size,
&mut max_instances,
);
let result = unsafe {
windows_sys::GetNamedPipeInfo(
handle as _,
&mut flags,
&mut out_buffer_size,
&mut in_buffer_size,
&mut max_instances,
)
};

if result == 0 {
return Err(io::Error::last_os_error());
Expand Down
2 changes: 1 addition & 1 deletion tokio/src/process/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -750,7 +750,7 @@ impl Command {
where
F: FnMut() -> io::Result<()> + Send + Sync + 'static,
{
self.std.pre_exec(f);
unsafe { self.std.pre_exec(f) };
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function is very short, and it’s clear enough for developers to reason about the safety requirements, so we don’t need additional "Safety" comments here”

self
}

Expand Down
2 changes: 1 addition & 1 deletion tokio/src/process/windows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ impl Drop for Waiting {
}

unsafe extern "system" fn callback(ptr: *mut std::ffi::c_void, _timer_fired: bool) {
let complete = &mut *(ptr as *mut Option<oneshot::Sender<()>>);
let complete = unsafe { &mut *(ptr as *mut Option<oneshot::Sender<()>>) };
let _ = complete.take().unwrap().send(());
}

Expand Down
6 changes: 5 additions & 1 deletion tokio/src/runtime/handle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,10 @@ impl Handle {

#[track_caller]
#[allow(dead_code)]
/// # Safety
///
/// This must only be called in `LocalRuntime` if the runtime has been verified to be owned
/// by the current thread.
pub(crate) unsafe fn spawn_local_named<F>(
&self,
future: F,
Expand All @@ -412,7 +416,7 @@ impl Handle {
let future = super::task::trace::Trace::root(future);
#[cfg(all(tokio_unstable, feature = "tracing"))]
let future = crate::util::trace::task(future, "task", meta, id.as_u64());
self.inner.spawn_local(future, id, meta.spawned_at)
unsafe { self.inner.spawn_local(future, id, meta.spawned_at) }
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function is very short, and it’s clear enough for developers to reason about the safety requirements, so we don’t need additional "Safety" comments here”

}

/// Returns the flavor of the current `Runtime`.
Expand Down
7 changes: 5 additions & 2 deletions tokio/src/runtime/io/registration_set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,8 @@ impl RegistrationSet {
let io = unsafe { NonNull::new_unchecked(Arc::as_ptr(io).cast_mut()) };

super::EXPOSE_IO.unexpose_provenance(io.as_ptr());
let _ = synced.registrations.remove(io);
// SAFETY: the caller guarantees that `io` is part of this list.
let _ = unsafe { synced.registrations.remove(io) };
}
}

Expand All @@ -141,6 +142,8 @@ unsafe impl linked_list::Link for Arc<ScheduledIo> {
unsafe fn pointers(
target: NonNull<Self::Target>,
) -> NonNull<linked_list::Pointers<ScheduledIo>> {
NonNull::new_unchecked(target.as_ref().linked_list_pointers.get())
// safety: `target.as_ref().linked_list_pointers` is a `UnsafeCell` that
// always returns a non-null pointer.
unsafe { NonNull::new_unchecked(target.as_ref().linked_list_pointers.get()) }
}
}
2 changes: 1 addition & 1 deletion tokio/src/runtime/io/scheduled_io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,7 @@ unsafe impl linked_list::Link for Waiter {
}

unsafe fn pointers(target: NonNull<Waiter>) -> NonNull<linked_list::Pointers<Waiter>> {
Waiter::addr_of_pointers(target)
unsafe { Waiter::addr_of_pointers(target) }
}
}

Expand Down
Loading
Loading