diff --git a/tokio/src/future/poll_fn.rs b/tokio/src/future/poll_fn.rs index d82ce8961..041e3d70a 100644 --- a/tokio/src/future/poll_fn.rs +++ b/tokio/src/future/poll_fn.rs @@ -35,6 +35,6 @@ where type Output = T; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { - (&mut self.f)(cx) + (self.f)(cx) } } diff --git a/tokio/src/io/util/vec_with_initialized.rs b/tokio/src/io/util/vec_with_initialized.rs index 208cc939c..a9b94e39d 100644 --- a/tokio/src/io/util/vec_with_initialized.rs +++ b/tokio/src/io/util/vec_with_initialized.rs @@ -1,19 +1,18 @@ use crate::io::ReadBuf; use std::mem::MaybeUninit; -mod private { - pub trait Sealed {} +/// Something that looks like a `Vec`. +/// +/// # Safety +/// +/// The implementor must guarantee that the vector returned by the +/// `as_mut` and `as_mut` methods do not change from one call to +/// another. +pub(crate) unsafe trait VecU8: AsRef> + AsMut> {} - impl Sealed for Vec {} - impl Sealed for &mut Vec {} -} +unsafe impl VecU8 for Vec {} +unsafe impl VecU8 for &mut Vec {} -/// A sealed trait that constrains the generic type parameter in `VecWithInitialized`. That struct's safety relies -/// on certain invariants upheld by `Vec`. -pub(crate) trait VecU8: AsMut> + private::Sealed {} - -impl VecU8 for Vec {} -impl VecU8 for &mut Vec {} /// This struct wraps a `Vec` or `&mut Vec`, combining it with a /// `num_initialized`, which keeps track of the number of initialized bytes /// in the unused capacity. @@ -64,8 +63,8 @@ where } #[cfg(feature = "io-util")] - pub(crate) fn is_empty(&mut self) -> bool { - self.vec.as_mut().is_empty() + pub(crate) fn is_empty(&self) -> bool { + self.vec.as_ref().is_empty() } pub(crate) fn get_read_buf<'a>(&'a mut self) -> ReadBuf<'a> { diff --git a/tokio/src/net/addr.rs b/tokio/src/net/addr.rs index 36da86019..e592aeec0 100644 --- a/tokio/src/net/addr.rs +++ b/tokio/src/net/addr.rs @@ -136,16 +136,22 @@ impl sealed::ToSocketAddrsPriv for &[SocketAddr] { type Future = ReadyFuture; fn to_socket_addrs(&self, _: sealed::Internal) -> Self::Future { - // Clippy doesn't like the `to_vec()` call here (as it will allocate, - // while `self.iter().copied()` would not), but it's actually necessary - // in order to ensure that the returned iterator is valid for the - // `'static` lifetime, which the borrowed `slice::Iter` iterator would - // not be. + #[inline] + fn slice_to_vec(addrs: &[SocketAddr]) -> Vec { + addrs.to_vec() + } + + // This uses a helper method because clippy doesn't like the `to_vec()` + // call here (it will allocate, whereas `self.iter().copied()` would + // not), but it's actually necessary in order to ensure that the + // returned iterator is valid for the `'static` lifetime, which the + // borrowed `slice::Iter` iterator would not be. + // // Note that we can't actually add an `allow` attribute for // `clippy::unnecessary_to_owned` here, as Tokio's CI runs clippy lints // on Rust 1.52 to avoid breaking LTS releases of Tokio. Users of newer // Rust versions who see this lint should just ignore it. - let iter = self.to_vec().into_iter(); + let iter = slice_to_vec(self).into_iter(); future::ready(Ok(iter)) } }