diff --git a/Cargo.toml b/Cargo.toml index fd27d492b..55aa54386 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,7 +5,7 @@ name = "crossbeam" # - Update README.md # - Create "crossbeam-X.Y.Z" git tag version = "0.8.2" -edition = "2018" +edition = "2021" rust-version = "1.61" license = "MIT OR Apache-2.0" repository = "https://github.com/crossbeam-rs/crossbeam" @@ -68,7 +68,11 @@ default-features = false [dev-dependencies] rand = "0.8" +[lints] +workspace = true + [workspace] +resolver = "2" members = [ ".", "crossbeam-channel", @@ -79,3 +83,9 @@ members = [ "crossbeam-skiplist", "crossbeam-utils", ] + +[workspace.lints.rust] +missing_debug_implementations = "warn" +rust_2018_idioms = "warn" +single_use_lifetimes = "warn" +unreachable_pub = "warn" diff --git a/crossbeam-channel/Cargo.toml b/crossbeam-channel/Cargo.toml index a39e0d767..e80740d0b 100644 --- a/crossbeam-channel/Cargo.toml +++ b/crossbeam-channel/Cargo.toml @@ -5,7 +5,7 @@ name = "crossbeam-channel" # - Update README.md # - Create "crossbeam-channel-X.Y.Z" git tag version = "0.5.8" -edition = "2018" +edition = "2021" rust-version = "1.61" license = "MIT OR Apache-2.0" repository = "https://github.com/crossbeam-rs/crossbeam" @@ -36,3 +36,6 @@ optional = true num_cpus = "1.13.0" rand = "0.8" signal-hook = "0.3" + +[lints] +workspace = true diff --git a/crossbeam-channel/benchmarks/Cargo.toml b/crossbeam-channel/benchmarks/Cargo.toml index 8c86d8582..1ddf412fa 100644 --- a/crossbeam-channel/benchmarks/Cargo.toml +++ b/crossbeam-channel/benchmarks/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "benchmarks" version = "0.1.0" -edition = "2018" +edition = "2021" publish = false [dependencies] @@ -69,3 +69,6 @@ doc = false name = "mpmc" path = "mpmc.rs" doc = false + +[lints] +workspace = true diff --git a/crossbeam-channel/benchmarks/message.rs b/crossbeam-channel/benchmarks/message.rs index f8a921ec7..5c899b6fc 100644 --- a/crossbeam-channel/benchmarks/message.rs +++ b/crossbeam-channel/benchmarks/message.rs @@ -3,7 +3,7 @@ use std::fmt; const LEN: usize = 1; #[derive(Clone, Copy)] -pub struct Message(pub [usize; LEN]); +pub(crate) struct Message(pub(crate) [usize; LEN]); impl fmt::Debug for Message { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -12,6 +12,6 @@ impl fmt::Debug for Message { } #[inline] -pub fn new(num: usize) -> Message { +pub(crate) fn new(num: usize) -> Message { Message([num; LEN]) } diff --git a/crossbeam-channel/src/channel.rs b/crossbeam-channel/src/channel.rs index b08461298..bcbb09afc 100644 --- a/crossbeam-channel/src/channel.rs +++ b/crossbeam-channel/src/channel.rs @@ -648,7 +648,7 @@ impl Sender { /// let (s3, _) = unbounded(); /// assert!(!s.same_channel(&s3)); /// ``` - pub fn same_channel(&self, other: &Sender) -> bool { + pub fn same_channel(&self, other: &Self) -> bool { match (&self.flavor, &other.flavor) { (SenderFlavor::Array(ref a), SenderFlavor::Array(ref b)) => a == b, (SenderFlavor::List(ref a), SenderFlavor::List(ref b)) => a == b, @@ -678,7 +678,7 @@ impl Clone for Sender { SenderFlavor::Zero(chan) => SenderFlavor::Zero(chan.acquire()), }; - Sender { flavor } + Self { flavor } } } @@ -1142,7 +1142,7 @@ impl Receiver { /// let (_, r3) = unbounded(); /// assert!(!r.same_channel(&r3)); /// ``` - pub fn same_channel(&self, other: &Receiver) -> bool { + pub fn same_channel(&self, other: &Self) -> bool { match (&self.flavor, &other.flavor) { (ReceiverFlavor::Array(a), ReceiverFlavor::Array(b)) => a == b, (ReceiverFlavor::List(a), ReceiverFlavor::List(b)) => a == b, @@ -1181,7 +1181,7 @@ impl Clone for Receiver { ReceiverFlavor::Never(_) => ReceiverFlavor::Never(flavors::never::Channel::new()), }; - Receiver { flavor } + Self { flavor } } } diff --git a/crossbeam-channel/src/context.rs b/crossbeam-channel/src/context.rs index 7467b802c..22bedf9ce 100644 --- a/crossbeam-channel/src/context.rs +++ b/crossbeam-channel/src/context.rs @@ -39,7 +39,7 @@ impl Context { #[inline] pub fn with(f: F) -> R where - F: FnOnce(&Context) -> R, + F: FnOnce(&Self) -> R, { thread_local! { /// Cached thread-local context. @@ -47,14 +47,14 @@ impl Context { } let mut f = Some(f); - let mut f = |cx: &Context| -> R { + let mut f = |cx: &Self| -> R { let f = f.take().unwrap(); f(cx) }; CONTEXT .try_with(|cell| match cell.take() { - None => f(&Context::new()), + None => f(&Self::new()), Some(cx) => { cx.reset(); let res = f(&cx); @@ -62,13 +62,13 @@ impl Context { res } }) - .unwrap_or_else(|_| f(&Context::new())) + .unwrap_or_else(|_| f(&Self::new())) } /// Creates a new `Context`. #[cold] - fn new() -> Context { - Context { + fn new() -> Self { + Self { inner: Arc::new(Inner { select: AtomicUsize::new(Selected::Waiting.into()), packet: AtomicPtr::new(ptr::null_mut()), diff --git a/crossbeam-channel/src/counter.rs b/crossbeam-channel/src/counter.rs index 2c27f7c6b..396dd7173 100644 --- a/crossbeam-channel/src/counter.rs +++ b/crossbeam-channel/src/counter.rs @@ -45,7 +45,7 @@ impl Sender { } /// Acquires another sender reference. - pub(crate) fn acquire(&self) -> Sender { + pub(crate) fn acquire(&self) -> Self { let count = self.counter().senders.fetch_add(1, Ordering::Relaxed); // Cloning senders and calling `mem::forget` on the clones could potentially overflow the @@ -55,7 +55,7 @@ impl Sender { process::abort(); } - Sender { + Self { counter: self.counter, } } @@ -83,7 +83,7 @@ impl ops::Deref for Sender { } impl PartialEq for Sender { - fn eq(&self, other: &Sender) -> bool { + fn eq(&self, other: &Self) -> bool { self.counter == other.counter } } @@ -100,7 +100,7 @@ impl Receiver { } /// Acquires another receiver reference. - pub(crate) fn acquire(&self) -> Receiver { + pub(crate) fn acquire(&self) -> Self { let count = self.counter().receivers.fetch_add(1, Ordering::Relaxed); // Cloning receivers and calling `mem::forget` on the clones could potentially overflow the @@ -110,7 +110,7 @@ impl Receiver { process::abort(); } - Receiver { + Self { counter: self.counter, } } @@ -138,7 +138,7 @@ impl ops::Deref for Receiver { } impl PartialEq for Receiver { - fn eq(&self, other: &Receiver) -> bool { + fn eq(&self, other: &Self) -> bool { self.counter == other.counter } } diff --git a/crossbeam-channel/src/err.rs b/crossbeam-channel/src/err.rs index 293e13b3a..7306c46d5 100644 --- a/crossbeam-channel/src/err.rs +++ b/crossbeam-channel/src/err.rs @@ -152,8 +152,8 @@ impl SendError { impl fmt::Debug for TrySendError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match *self { - TrySendError::Full(..) => "Full(..)".fmt(f), - TrySendError::Disconnected(..) => "Disconnected(..)".fmt(f), + Self::Full(..) => "Full(..)".fmt(f), + Self::Disconnected(..) => "Disconnected(..)".fmt(f), } } } @@ -161,8 +161,8 @@ impl fmt::Debug for TrySendError { impl fmt::Display for TrySendError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match *self { - TrySendError::Full(..) => "sending on a full channel".fmt(f), - TrySendError::Disconnected(..) => "sending on a disconnected channel".fmt(f), + Self::Full(..) => "sending on a full channel".fmt(f), + Self::Disconnected(..) => "sending on a disconnected channel".fmt(f), } } } @@ -170,9 +170,9 @@ impl fmt::Display for TrySendError { impl error::Error for TrySendError {} impl From> for TrySendError { - fn from(err: SendError) -> TrySendError { + fn from(err: SendError) -> Self { match err { - SendError(t) => TrySendError::Disconnected(t), + SendError(t) => Self::Disconnected(t), } } } @@ -193,19 +193,19 @@ impl TrySendError { /// ``` pub fn into_inner(self) -> T { match self { - TrySendError::Full(v) => v, - TrySendError::Disconnected(v) => v, + Self::Full(v) => v, + Self::Disconnected(v) => v, } } /// Returns `true` if the send operation failed because the channel is full. pub fn is_full(&self) -> bool { - matches!(self, TrySendError::Full(_)) + matches!(self, Self::Full(_)) } /// Returns `true` if the send operation failed because the channel is disconnected. pub fn is_disconnected(&self) -> bool { - matches!(self, TrySendError::Disconnected(_)) + matches!(self, Self::Disconnected(_)) } } @@ -218,8 +218,8 @@ impl fmt::Debug for SendTimeoutError { impl fmt::Display for SendTimeoutError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match *self { - SendTimeoutError::Timeout(..) => "timed out waiting on send operation".fmt(f), - SendTimeoutError::Disconnected(..) => "sending on a disconnected channel".fmt(f), + Self::Timeout(..) => "timed out waiting on send operation".fmt(f), + Self::Disconnected(..) => "sending on a disconnected channel".fmt(f), } } } @@ -227,9 +227,9 @@ impl fmt::Display for SendTimeoutError { impl error::Error for SendTimeoutError {} impl From> for SendTimeoutError { - fn from(err: SendError) -> SendTimeoutError { + fn from(err: SendError) -> Self { match err { - SendError(e) => SendTimeoutError::Disconnected(e), + SendError(e) => Self::Disconnected(e), } } } @@ -251,19 +251,19 @@ impl SendTimeoutError { /// ``` pub fn into_inner(self) -> T { match self { - SendTimeoutError::Timeout(v) => v, - SendTimeoutError::Disconnected(v) => v, + Self::Timeout(v) => v, + Self::Disconnected(v) => v, } } /// Returns `true` if the send operation timed out. pub fn is_timeout(&self) -> bool { - matches!(self, SendTimeoutError::Timeout(_)) + matches!(self, Self::Timeout(_)) } /// Returns `true` if the send operation failed because the channel is disconnected. pub fn is_disconnected(&self) -> bool { - matches!(self, SendTimeoutError::Disconnected(_)) + matches!(self, Self::Disconnected(_)) } } @@ -278,8 +278,8 @@ impl error::Error for RecvError {} impl fmt::Display for TryRecvError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match *self { - TryRecvError::Empty => "receiving on an empty channel".fmt(f), - TryRecvError::Disconnected => "receiving on an empty and disconnected channel".fmt(f), + Self::Empty => "receiving on an empty channel".fmt(f), + Self::Disconnected => "receiving on an empty and disconnected channel".fmt(f), } } } @@ -287,9 +287,9 @@ impl fmt::Display for TryRecvError { impl error::Error for TryRecvError {} impl From for TryRecvError { - fn from(err: RecvError) -> TryRecvError { + fn from(err: RecvError) -> Self { match err { - RecvError => TryRecvError::Disconnected, + RecvError => Self::Disconnected, } } } @@ -297,20 +297,20 @@ impl From for TryRecvError { impl TryRecvError { /// Returns `true` if the receive operation failed because the channel is empty. pub fn is_empty(&self) -> bool { - matches!(self, TryRecvError::Empty) + matches!(self, Self::Empty) } /// Returns `true` if the receive operation failed because the channel is disconnected. pub fn is_disconnected(&self) -> bool { - matches!(self, TryRecvError::Disconnected) + matches!(self, Self::Disconnected) } } impl fmt::Display for RecvTimeoutError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match *self { - RecvTimeoutError::Timeout => "timed out waiting on receive operation".fmt(f), - RecvTimeoutError::Disconnected => "channel is empty and disconnected".fmt(f), + Self::Timeout => "timed out waiting on receive operation".fmt(f), + Self::Disconnected => "channel is empty and disconnected".fmt(f), } } } @@ -318,9 +318,9 @@ impl fmt::Display for RecvTimeoutError { impl error::Error for RecvTimeoutError {} impl From for RecvTimeoutError { - fn from(err: RecvError) -> RecvTimeoutError { + fn from(err: RecvError) -> Self { match err { - RecvError => RecvTimeoutError::Disconnected, + RecvError => Self::Disconnected, } } } @@ -328,12 +328,12 @@ impl From for RecvTimeoutError { impl RecvTimeoutError { /// Returns `true` if the receive operation timed out. pub fn is_timeout(&self) -> bool { - matches!(self, RecvTimeoutError::Timeout) + matches!(self, Self::Timeout) } /// Returns `true` if the receive operation failed because the channel is disconnected. pub fn is_disconnected(&self) -> bool { - matches!(self, RecvTimeoutError::Disconnected) + matches!(self, Self::Disconnected) } } diff --git a/crossbeam-channel/src/flavors/array.rs b/crossbeam-channel/src/flavors/array.rs index 63b82eb85..16ec7ac51 100644 --- a/crossbeam-channel/src/flavors/array.rs +++ b/crossbeam-channel/src/flavors/array.rs @@ -43,7 +43,7 @@ pub(crate) struct ArrayToken { impl Default for ArrayToken { #[inline] fn default() -> Self { - ArrayToken { + Self { slot: ptr::null(), stamp: 0, } @@ -115,7 +115,7 @@ impl Channel { }) .collect(); - Channel { + Self { buffer, cap, one_lap, diff --git a/crossbeam-channel/src/flavors/at.rs b/crossbeam-channel/src/flavors/at.rs index 5caa2a007..83e69c1ed 100644 --- a/crossbeam-channel/src/flavors/at.rs +++ b/crossbeam-channel/src/flavors/at.rs @@ -27,7 +27,7 @@ impl Channel { /// Creates a channel that delivers a message at a certain instant in time. #[inline] pub(crate) fn new_deadline(when: Instant) -> Self { - Channel { + Self { delivery_time: when, received: AtomicBool::new(false), } diff --git a/crossbeam-channel/src/flavors/list.rs b/crossbeam-channel/src/flavors/list.rs index 230edd8d2..78a1ea365 100644 --- a/crossbeam-channel/src/flavors/list.rs +++ b/crossbeam-channel/src/flavors/list.rs @@ -76,7 +76,7 @@ struct Block { impl Block { /// Creates an empty block. - fn new() -> Block { + fn new() -> Self { Self { next: AtomicPtr::new(ptr::null_mut()), slots: [Slot::UNINIT; BLOCK_CAP], @@ -84,7 +84,7 @@ impl Block { } /// Waits until the next pointer is set. - fn wait_next(&self) -> *mut Block { + fn wait_next(&self) -> *mut Self { let backoff = Backoff::new(); loop { let next = self.next.load(Ordering::Acquire); @@ -96,7 +96,7 @@ impl Block { } /// Sets the `DESTROY` bit in slots starting from `start` and destroys the block. - unsafe fn destroy(this: *mut Block, start: usize) { + unsafe fn destroy(this: *mut Self, start: usize) { // It is not necessary to set the `DESTROY` bit in the last slot because that slot has // begun destruction of the block. for i in start..BLOCK_CAP - 1 { @@ -139,7 +139,7 @@ pub(crate) struct ListToken { impl Default for ListToken { #[inline] fn default() -> Self { - ListToken { + Self { block: ptr::null(), offset: 0, } @@ -170,7 +170,7 @@ pub(crate) struct Channel { impl Channel { /// Creates a new unbounded channel. pub(crate) fn new() -> Self { - Channel { + Self { head: CachePadded::new(Position { block: AtomicPtr::new(ptr::null_mut()), index: AtomicUsize::new(0), diff --git a/crossbeam-channel/src/flavors/never.rs b/crossbeam-channel/src/flavors/never.rs index 277a61dc1..7a9f830ac 100644 --- a/crossbeam-channel/src/flavors/never.rs +++ b/crossbeam-channel/src/flavors/never.rs @@ -22,7 +22,7 @@ impl Channel { /// Creates a channel that never delivers messages. #[inline] pub(crate) fn new() -> Self { - Channel { + Self { _marker: PhantomData, } } diff --git a/crossbeam-channel/src/flavors/tick.rs b/crossbeam-channel/src/flavors/tick.rs index bc3d338b8..a5b67ed9e 100644 --- a/crossbeam-channel/src/flavors/tick.rs +++ b/crossbeam-channel/src/flavors/tick.rs @@ -27,7 +27,7 @@ impl Channel { /// Creates a channel that delivers messages periodically. #[inline] pub(crate) fn new(delivery_time: Instant, dur: Duration) -> Self { - Channel { + Self { delivery_time: AtomicCell::new(delivery_time), duration: dur, } diff --git a/crossbeam-channel/src/flavors/zero.rs b/crossbeam-channel/src/flavors/zero.rs index aae2ea300..391857536 100644 --- a/crossbeam-channel/src/flavors/zero.rs +++ b/crossbeam-channel/src/flavors/zero.rs @@ -45,8 +45,8 @@ struct Packet { impl Packet { /// Creates an empty packet on the stack. - fn empty_on_stack() -> Packet { - Packet { + fn empty_on_stack() -> Self { + Self { on_stack: true, ready: AtomicBool::new(false), msg: UnsafeCell::new(None), @@ -54,8 +54,8 @@ impl Packet { } /// Creates an empty packet on the heap. - fn empty_on_heap() -> Box> { - Box::new(Packet { + fn empty_on_heap() -> Box { + Box::new(Self { on_stack: false, ready: AtomicBool::new(false), msg: UnsafeCell::new(None), @@ -63,8 +63,8 @@ impl Packet { } /// Creates a packet on the stack, containing a message. - fn message_on_stack(msg: T) -> Packet { - Packet { + fn message_on_stack(msg: T) -> Self { + Self { on_stack: true, ready: AtomicBool::new(false), msg: UnsafeCell::new(Some(msg)), @@ -104,7 +104,7 @@ pub(crate) struct Channel { impl Channel { /// Constructs a new zero-capacity channel. pub(crate) fn new() -> Self { - Channel { + Self { inner: Mutex::new(Inner { senders: Waker::new(), receivers: Waker::new(), diff --git a/crossbeam-channel/src/lib.rs b/crossbeam-channel/src/lib.rs index 74cc66c2d..a3f29a712 100644 --- a/crossbeam-channel/src/lib.rs +++ b/crossbeam-channel/src/lib.rs @@ -328,16 +328,11 @@ #![doc(test( no_crate_inject, attr( - deny(warnings, rust_2018_idioms), + deny(warnings, rust_2018_idioms, single_use_lifetimes), allow(dead_code, unused_assignments, unused_variables) ) ))] -#![warn( - missing_docs, - missing_debug_implementations, - rust_2018_idioms, - unreachable_pub -)] +#![warn(missing_docs)] #![cfg_attr(not(feature = "std"), no_std)] use cfg_if::cfg_if; diff --git a/crossbeam-channel/src/select.rs b/crossbeam-channel/src/select.rs index 7546b5b70..108eb04f7 100644 --- a/crossbeam-channel/src/select.rs +++ b/crossbeam-channel/src/select.rs @@ -42,12 +42,12 @@ impl Operation { /// reference should point to a variable that is specific to the thread and the operation, /// and is alive for the entire duration of select or blocking operation. #[inline] - pub fn hook(r: &mut T) -> Operation { + pub fn hook(r: &mut T) -> Self { let val = r as *mut T as usize; // Make sure that the pointer address doesn't equal the numerical representation of // `Selected::{Waiting, Aborted, Disconnected}`. assert!(val > 2); - Operation(val) + Self(val) } } @@ -69,12 +69,12 @@ pub enum Selected { impl From for Selected { #[inline] - fn from(val: usize) -> Selected { + fn from(val: usize) -> Self { match val { - 0 => Selected::Waiting, - 1 => Selected::Aborted, - 2 => Selected::Disconnected, - oper => Selected::Operation(Operation(oper)), + 0 => Self::Waiting, + 1 => Self::Aborted, + 2 => Self::Disconnected, + oper => Self::Operation(Operation(oper)), } } } @@ -618,8 +618,8 @@ impl<'a> Select<'a> { /// // The list of operations is empty, which means no operation can be selected. /// assert!(sel.try_select().is_err()); /// ``` - pub fn new() -> Select<'a> { - Select { + pub fn new() -> Self { + Self { handles: Vec::with_capacity(4), next_index: 0, } @@ -1128,18 +1128,18 @@ impl<'a> Select<'a> { } } -impl<'a> Clone for Select<'a> { - fn clone(&self) -> Select<'a> { - Select { +impl Clone for Select<'_> { + fn clone(&self) -> Self { + Self { handles: self.handles.clone(), next_index: self.next_index, } } } -impl<'a> Default for Select<'a> { - fn default() -> Select<'a> { - Select::new() +impl Default for Select<'_> { + fn default() -> Self { + Self::new() } } diff --git a/crossbeam-channel/src/select_macro.rs b/crossbeam-channel/src/select_macro.rs index 9ac87903d..3b71e1e50 100644 --- a/crossbeam-channel/src/select_macro.rs +++ b/crossbeam-channel/src/select_macro.rs @@ -685,7 +685,7 @@ macro_rules! crossbeam_channel_internal { $default:tt ) => {{ const _LEN: usize = $crate::crossbeam_channel_internal!(@count ($($cases)*)); - let _handle: &$crate::internal::SelectHandle = &$crate::never::<()>(); + let _handle: &dyn $crate::internal::SelectHandle = &$crate::never::<()>(); #[allow(unused_mut)] let mut _sel = [(_handle, 0, ::std::ptr::null()); _LEN]; diff --git a/crossbeam-channel/src/waker.rs b/crossbeam-channel/src/waker.rs index 7eb58ba7f..abb2bdb42 100644 --- a/crossbeam-channel/src/waker.rs +++ b/crossbeam-channel/src/waker.rs @@ -36,7 +36,7 @@ impl Waker { /// Creates a new `Waker`. #[inline] pub(crate) fn new() -> Self { - Waker { + Self { selectors: Vec::new(), observers: Vec::new(), } @@ -186,7 +186,7 @@ impl SyncWaker { /// Creates a new `SyncWaker`. #[inline] pub(crate) fn new() -> Self { - SyncWaker { + Self { inner: Mutex::new(Waker::new()), is_empty: AtomicBool::new(true), } diff --git a/crossbeam-channel/tests/golang.rs b/crossbeam-channel/tests/golang.rs index 19865badc..d1c2626e9 100644 --- a/crossbeam-channel/tests/golang.rs +++ b/crossbeam-channel/tests/golang.rs @@ -42,8 +42,8 @@ struct ChanInner { } impl Clone for Chan { - fn clone(&self) -> Chan { - Chan { + fn clone(&self) -> Self { + Self { inner: self.inner.clone(), } } @@ -123,7 +123,7 @@ impl Iterator for Chan { } } -impl<'a, T> IntoIterator for &'a Chan { +impl IntoIterator for &Chan { type Item = T; type IntoIter = Chan; @@ -169,8 +169,8 @@ struct WaitGroupInner { } impl WaitGroup { - fn new() -> WaitGroup { - WaitGroup(Arc::new(WaitGroupInner { + fn new() -> Self { + Self(Arc::new(WaitGroupInner { cond: Condvar::new(), count: Mutex::new(0), })) @@ -1621,7 +1621,7 @@ mod chan { impl ChanWithVals { fn with_capacity(capacity: usize) -> Self { - ChanWithVals { + Self { chan: make(capacity), sv: Arc::new(AtomicI32::new(0)), rv: Arc::new(AtomicI32::new(0)), @@ -1629,7 +1629,7 @@ mod chan { } fn closed() -> Self { - let ch = ChanWithVals::with_capacity(0); + let ch = Self::with_capacity(0); ch.chan.close_r(); ch.chan.close_s(); ch @@ -1674,7 +1674,7 @@ mod chan { impl Clone for ChanWithVals { fn clone(&self) -> Self { - ChanWithVals { + Self { chan: self.chan.clone(), sv: self.sv.clone(), rv: self.rv.clone(), @@ -1702,7 +1702,7 @@ mod chan { impl Clone for Context { fn clone(&self) -> Self { - Context { + Self { nproc: self.nproc.clone(), cval: self.cval.clone(), tot: self.tot.clone(), diff --git a/crossbeam-channel/tests/mpsc.rs b/crossbeam-channel/tests/mpsc.rs index b2c3a762a..9ba2aac8a 100644 --- a/crossbeam-channel/tests/mpsc.rs +++ b/crossbeam-channel/tests/mpsc.rs @@ -29,34 +29,34 @@ use std::time::Duration; use crossbeam_channel as cc; -pub struct Sender { - pub inner: cc::Sender, +struct Sender { + inner: cc::Sender, } impl Sender { - pub fn send(&self, t: T) -> Result<(), SendError> { + fn send(&self, t: T) -> Result<(), SendError> { self.inner.send(t).map_err(|cc::SendError(m)| SendError(m)) } } impl Clone for Sender { - fn clone(&self) -> Sender { - Sender { + fn clone(&self) -> Self { + Self { inner: self.inner.clone(), } } } -pub struct SyncSender { - pub inner: cc::Sender, +struct SyncSender { + inner: cc::Sender, } impl SyncSender { - pub fn send(&self, t: T) -> Result<(), SendError> { + fn send(&self, t: T) -> Result<(), SendError> { self.inner.send(t).map_err(|cc::SendError(m)| SendError(m)) } - pub fn try_send(&self, t: T) -> Result<(), TrySendError> { + fn try_send(&self, t: T) -> Result<(), TrySendError> { self.inner.try_send(t).map_err(|err| match err { cc::TrySendError::Full(m) => TrySendError::Full(m), cc::TrySendError::Disconnected(m) => TrySendError::Disconnected(m), @@ -65,41 +65,41 @@ impl SyncSender { } impl Clone for SyncSender { - fn clone(&self) -> SyncSender { - SyncSender { + fn clone(&self) -> Self { + Self { inner: self.inner.clone(), } } } -pub struct Receiver { - pub inner: cc::Receiver, +struct Receiver { + inner: cc::Receiver, } impl Receiver { - pub fn try_recv(&self) -> Result { + fn try_recv(&self) -> Result { self.inner.try_recv().map_err(|err| match err { cc::TryRecvError::Empty => TryRecvError::Empty, cc::TryRecvError::Disconnected => TryRecvError::Disconnected, }) } - pub fn recv(&self) -> Result { + fn recv(&self) -> Result { self.inner.recv().map_err(|_| RecvError) } - pub fn recv_timeout(&self, timeout: Duration) -> Result { + fn recv_timeout(&self, timeout: Duration) -> Result { self.inner.recv_timeout(timeout).map_err(|err| match err { cc::RecvTimeoutError::Timeout => RecvTimeoutError::Timeout, cc::RecvTimeoutError::Disconnected => RecvTimeoutError::Disconnected, }) } - pub fn iter(&self) -> Iter { + fn iter(&self) -> Iter<'_, T> { Iter { inner: self } } - pub fn try_iter(&self) -> TryIter { + fn try_iter(&self) -> TryIter<'_, T> { TryIter { inner: self } } } @@ -122,11 +122,11 @@ impl IntoIterator for Receiver { } } -pub struct TryIter<'a, T: 'a> { +struct TryIter<'a, T> { inner: &'a Receiver, } -impl<'a, T> Iterator for TryIter<'a, T> { +impl Iterator for TryIter<'_, T> { type Item = T; fn next(&mut self) -> Option { @@ -134,11 +134,11 @@ impl<'a, T> Iterator for TryIter<'a, T> { } } -pub struct Iter<'a, T: 'a> { +struct Iter<'a, T> { inner: &'a Receiver, } -impl<'a, T> Iterator for Iter<'a, T> { +impl Iterator for Iter<'_, T> { type Item = T; fn next(&mut self) -> Option { @@ -146,7 +146,7 @@ impl<'a, T> Iterator for Iter<'a, T> { } } -pub struct IntoIter { +struct IntoIter { inner: Receiver, } @@ -158,14 +158,14 @@ impl Iterator for IntoIter { } } -pub fn channel() -> (Sender, Receiver) { +fn channel() -> (Sender, Receiver) { let (s, r) = cc::unbounded(); let s = Sender { inner: s }; let r = Receiver { inner: r }; (s, r) } -pub fn sync_channel(bound: usize) -> (SyncSender, Receiver) { +fn sync_channel(bound: usize) -> (SyncSender, Receiver) { let (s, r) = cc::bounded(bound); let s = SyncSender { inner: s }; let r = Receiver { inner: r }; @@ -195,7 +195,7 @@ mod channel_tests { use std::thread; use std::time::{Duration, Instant}; - pub fn stress_factor() -> usize { + fn stress_factor() -> usize { match env::var("RUST_TEST_STRESS") { Ok(val) => val.parse().unwrap(), Err(..) => 1, @@ -971,7 +971,7 @@ mod sync_channel_tests { use std::thread; use std::time::Duration; - pub fn stress_factor() -> usize { + fn stress_factor() -> usize { match env::var("RUST_TEST_STRESS") { Ok(val) => val.parse().unwrap(), Err(..) => 1, diff --git a/crossbeam-deque/Cargo.toml b/crossbeam-deque/Cargo.toml index c25889c9e..4fece07a5 100644 --- a/crossbeam-deque/Cargo.toml +++ b/crossbeam-deque/Cargo.toml @@ -5,7 +5,7 @@ name = "crossbeam-deque" # - Update README.md # - Create "crossbeam-deque-X.Y.Z" git tag version = "0.8.3" -edition = "2018" +edition = "2021" rust-version = "1.61" license = "MIT OR Apache-2.0" repository = "https://github.com/crossbeam-rs/crossbeam" @@ -40,3 +40,6 @@ optional = true [dev-dependencies] rand = "0.8" + +[lints] +workspace = true diff --git a/crossbeam-deque/src/deque.rs b/crossbeam-deque/src/deque.rs index 1356defb7..e733abae4 100644 --- a/crossbeam-deque/src/deque.rs +++ b/crossbeam-deque/src/deque.rs @@ -1,7 +1,6 @@ use std::cell::{Cell, UnsafeCell}; use std::cmp; use std::fmt; -use std::iter::FromIterator; use std::marker::PhantomData; use std::mem::{self, ManuallyDrop, MaybeUninit}; use std::ptr; @@ -35,13 +34,13 @@ unsafe impl Send for Buffer {} impl Buffer { /// Allocates a new buffer with the specified capacity. - fn alloc(cap: usize) -> Buffer { + fn alloc(cap: usize) -> Self { debug_assert_eq!(cap, cap.next_power_of_two()); let mut v = ManuallyDrop::new(Vec::with_capacity(cap)); let ptr = v.as_mut_ptr(); - Buffer { ptr, cap } + Self { ptr, cap } } /// Deallocates the buffer. @@ -79,7 +78,7 @@ impl Buffer { } impl Clone for Buffer { - fn clone(&self) -> Buffer { + fn clone(&self) -> Self { *self } } @@ -210,7 +209,7 @@ impl Worker { /// /// let w = Worker::::new_fifo(); /// ``` - pub fn new_fifo() -> Worker { + pub fn new_fifo() -> Self { let buffer = Buffer::alloc(MIN_CAP); let inner = Arc::new(CachePadded::new(Inner { @@ -219,7 +218,7 @@ impl Worker { buffer: CachePadded::new(Atomic::new(buffer)), })); - Worker { + Self { inner, buffer: Cell::new(buffer), flavor: Flavor::Fifo, @@ -238,7 +237,7 @@ impl Worker { /// /// let w = Worker::::new_lifo(); /// ``` - pub fn new_lifo() -> Worker { + pub fn new_lifo() -> Self { let buffer = Buffer::alloc(MIN_CAP); let inner = Arc::new(CachePadded::new(Inner { @@ -247,7 +246,7 @@ impl Worker { buffer: CachePadded::new(Atomic::new(buffer)), })); - Worker { + Self { inner, buffer: Cell::new(buffer), flavor: Flavor::Lifo, @@ -1155,8 +1154,8 @@ impl Stealer { } impl Clone for Stealer { - fn clone(&self) -> Stealer { - Stealer { + fn clone(&self) -> Self { + Self { inner: self.inner.clone(), flavor: self.flavor, } @@ -1223,7 +1222,7 @@ struct Block { impl Block { /// Creates an empty block that starts at `start_index`. - fn new() -> Block { + fn new() -> Self { Self { next: AtomicPtr::new(ptr::null_mut()), slots: [Slot::UNINIT; BLOCK_CAP], @@ -1231,7 +1230,7 @@ impl Block { } /// Waits until the next pointer is set. - fn wait_next(&self) -> *mut Block { + fn wait_next(&self) -> *mut Self { let backoff = Backoff::new(); loop { let next = self.next.load(Ordering::Acquire); @@ -1243,7 +1242,7 @@ impl Block { } /// Sets the `DESTROY` bit in slots starting from `start` and destroys the block. - unsafe fn destroy(this: *mut Block, count: usize) { + unsafe fn destroy(this: *mut Self, count: usize) { // It is not necessary to set the `DESTROY` bit in the last slot because that slot has // begun destruction of the block. for i in (0..count).rev() { @@ -1331,7 +1330,7 @@ impl Injector { /// /// let q = Injector::::new(); /// ``` - pub fn new() -> Injector { + pub fn new() -> Self { Self::default() } @@ -2056,7 +2055,7 @@ impl Steal { /// assert!(Empty::.is_empty()); /// ``` pub fn is_empty(&self) -> bool { - matches!(self, Steal::Empty) + matches!(self, Self::Empty) } /// Returns `true` if at least one task was stolen. @@ -2072,7 +2071,7 @@ impl Steal { /// assert!(Success(7).is_success()); /// ``` pub fn is_success(&self) -> bool { - matches!(self, Steal::Success(_)) + matches!(self, Self::Success(_)) } /// Returns `true` if the steal operation needs to be retried. @@ -2088,7 +2087,7 @@ impl Steal { /// assert!(Retry::.is_retry()); /// ``` pub fn is_retry(&self) -> bool { - matches!(self, Steal::Retry) + matches!(self, Self::Retry) } /// Returns the result of the operation, if successful. @@ -2105,7 +2104,7 @@ impl Steal { /// ``` pub fn success(self) -> Option { match self { - Steal::Success(res) => Some(res), + Self::Success(res) => Some(res), _ => None, } } @@ -2131,18 +2130,18 @@ impl Steal { /// /// assert_eq!(Empty.or_else(|| Empty), Empty::); /// ``` - pub fn or_else(self, f: F) -> Steal + pub fn or_else(self, f: F) -> Self where - F: FnOnce() -> Steal, + F: FnOnce() -> Self, { match self { - Steal::Empty => f(), - Steal::Success(_) => self, - Steal::Retry => { - if let Steal::Success(res) = f() { - Steal::Success(res) + Self::Empty => f(), + Self::Success(_) => self, + Self::Retry => { + if let Self::Success(res) = f() { + Self::Success(res) } else { - Steal::Retry + Self::Retry } } } @@ -2152,35 +2151,35 @@ impl Steal { impl fmt::Debug for Steal { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { - Steal::Empty => f.pad("Empty"), - Steal::Success(_) => f.pad("Success(..)"), - Steal::Retry => f.pad("Retry"), + Self::Empty => f.pad("Empty"), + Self::Success(_) => f.pad("Success(..)"), + Self::Retry => f.pad("Retry"), } } } -impl FromIterator> for Steal { +impl FromIterator for Steal { /// Consumes items until a `Success` is found and returns it. /// /// If no `Success` was found, but there was at least one `Retry`, then returns `Retry`. /// Otherwise, `Empty` is returned. - fn from_iter(iter: I) -> Steal + fn from_iter(iter: I) -> Self where - I: IntoIterator>, + I: IntoIterator, { let mut retry = false; for s in iter { match &s { - Steal::Empty => {} - Steal::Success(_) => return s, - Steal::Retry => retry = true, + Self::Empty => {} + Self::Success(_) => return s, + Self::Retry => retry = true, } } if retry { - Steal::Retry + Self::Retry } else { - Steal::Empty + Self::Empty } } } diff --git a/crossbeam-deque/src/lib.rs b/crossbeam-deque/src/lib.rs index 16bc728b3..4a68b0b7c 100644 --- a/crossbeam-deque/src/lib.rs +++ b/crossbeam-deque/src/lib.rs @@ -85,16 +85,11 @@ #![doc(test( no_crate_inject, attr( - deny(warnings, rust_2018_idioms), + deny(warnings, rust_2018_idioms, single_use_lifetimes), allow(dead_code, unused_assignments, unused_variables) ) ))] -#![warn( - missing_docs, - missing_debug_implementations, - rust_2018_idioms, - unreachable_pub -)] +#![warn(missing_docs)] #![cfg_attr(not(feature = "std"), no_std)] use cfg_if::cfg_if; diff --git a/crossbeam-epoch/Cargo.toml b/crossbeam-epoch/Cargo.toml index 0c7e5b5db..d959a447c 100644 --- a/crossbeam-epoch/Cargo.toml +++ b/crossbeam-epoch/Cargo.toml @@ -5,7 +5,7 @@ name = "crossbeam-epoch" # - Update README.md # - Create "crossbeam-epoch-X.Y.Z" git tag version = "0.9.15" -edition = "2018" +edition = "2021" rust-version = "1.61" license = "MIT OR Apache-2.0" repository = "https://github.com/crossbeam-rs/crossbeam" @@ -39,7 +39,6 @@ autocfg = "1" [dependencies] cfg-if = "1" memoffset = "0.9" -scopeguard = { version = "1.1", default-features = false } # Enable the use of loom for concurrency testing. # @@ -55,3 +54,6 @@ default-features = false [dev-dependencies] rand = "0.8" + +[lints] +workspace = true diff --git a/crossbeam-epoch/src/atomic.rs b/crossbeam-epoch/src/atomic.rs index 028b9bf9c..851aa0a1b 100644 --- a/crossbeam-epoch/src/atomic.rs +++ b/crossbeam-epoch/src/atomic.rs @@ -265,7 +265,7 @@ impl Atomic { /// let a = Atomic::new(1234); /// # unsafe { drop(a.into_owned()); } // avoid leak /// ``` - pub fn new(init: T) -> Atomic { + pub fn new(init: T) -> Self { Self::init(init) } } @@ -281,7 +281,7 @@ impl Atomic { /// let a = Atomic::::init(1234); /// # unsafe { drop(a.into_owned()); } // avoid leak /// ``` - pub fn init(init: T::Init) -> Atomic { + pub fn init(init: T::Init) -> Self { Self::from(Owned::init(init)) } @@ -303,7 +303,7 @@ impl Atomic { /// let a = Atomic::::null(); /// ``` #[cfg(not(crossbeam_loom))] - pub const fn null() -> Atomic { + pub const fn null() -> Self { Self { data: AtomicPtr::new(ptr::null_mut()), _marker: PhantomData, @@ -311,7 +311,7 @@ impl Atomic { } /// Returns a new null atomic pointer. #[cfg(crossbeam_loom)] - pub fn null() -> Atomic { + pub fn null() -> Self { Self { data: AtomicPtr::new(ptr::null_mut()), _marker: PhantomData, @@ -846,13 +846,13 @@ impl Clone for Atomic { /// atomics or fences. fn clone(&self) -> Self { let data = self.data.load(Ordering::Relaxed); - Atomic::from_ptr(data) + Self::from_ptr(data) } } impl Default for Atomic { fn default() -> Self { - Atomic::null() + Self::null() } } @@ -991,7 +991,7 @@ impl Owned { /// /// let o = unsafe { Owned::from_raw(Box::into_raw(Box::new(1234))) }; /// ``` - pub unsafe fn from_raw(raw: *mut T) -> Owned { + pub unsafe fn from_raw(raw: *mut T) -> Self { let raw = raw.cast::<()>(); ensure_aligned::(raw); Self::from_ptr(raw) @@ -1023,7 +1023,7 @@ impl Owned { /// /// let o = Owned::new(1234); /// ``` - pub fn new(init: T) -> Owned { + pub fn new(init: T) -> Self { Self::init(init) } } @@ -1038,7 +1038,7 @@ impl Owned { /// /// let o = Owned::::init(1234); /// ``` - pub fn init(init: T::Init) -> Owned { + pub fn init(init: T::Init) -> Self { unsafe { Self::from_ptr(T::init(init)) } } @@ -1086,7 +1086,7 @@ impl Owned { /// let o = o.with_tag(2); /// assert_eq!(o.tag(), 2); /// ``` - pub fn with_tag(self, tag: usize) -> Owned { + pub fn with_tag(self, tag: usize) -> Self { let data = self.into_ptr(); unsafe { Self::from_ptr(compose_tag::(data, tag)) } } @@ -1114,7 +1114,7 @@ impl fmt::Debug for Owned { impl Clone for Owned { fn clone(&self) -> Self { - Owned::new((**self).clone()).with_tag(self.tag()) + Self::new((**self).clone()).with_tag(self.tag()) } } @@ -1136,7 +1136,7 @@ impl DerefMut for Owned { impl From for Owned { fn from(t: T) -> Self { - Owned::new(t) + Self::new(t) } } @@ -1218,7 +1218,7 @@ impl Pointer for Shared<'_, T> { } } -impl<'g, T> Shared<'g, T> { +impl Shared<'_, T> { /// Converts the pointer to a raw pointer (without the tag). /// /// # Examples @@ -1253,8 +1253,8 @@ impl<'g, T: ?Sized + Pointable> Shared<'g, T> { /// let p = Shared::::null(); /// assert!(p.is_null()); /// ``` - pub fn null() -> Shared<'g, T> { - Shared { + pub fn null() -> Self { + Self { data: ptr::null_mut(), _marker: PhantomData, } @@ -1564,7 +1564,7 @@ impl fmt::Pointer for Shared<'_, T> { impl Default for Shared<'_, T> { fn default() -> Self { - Shared::null() + Self::null() } } diff --git a/crossbeam-epoch/src/collector.rs b/crossbeam-epoch/src/collector.rs index d884e5e1e..6e60dd013 100644 --- a/crossbeam-epoch/src/collector.rs +++ b/crossbeam-epoch/src/collector.rs @@ -50,7 +50,7 @@ impl Collector { impl Clone for Collector { /// Creates another reference to the same garbage collector. fn clone(&self) -> Self { - Collector { + Self { global: self.global.clone(), } } @@ -64,7 +64,7 @@ impl fmt::Debug for Collector { impl PartialEq for Collector { /// Checks if both handles point to the same collector. - fn eq(&self, rhs: &Collector) -> bool { + fn eq(&self, rhs: &Self) -> bool { Arc::ptr_eq(&self.global, &rhs.global) } } diff --git a/crossbeam-epoch/src/deferred.rs b/crossbeam-epoch/src/deferred.rs index 041955f52..f2037dcbb 100644 --- a/crossbeam-epoch/src/deferred.rs +++ b/crossbeam-epoch/src/deferred.rs @@ -53,7 +53,7 @@ impl Deferred { f(); } - Deferred { + Self { call: call::, data, _marker: PhantomData, @@ -70,7 +70,7 @@ impl Deferred { (*b)(); } - Deferred { + Self { call: call::, data, _marker: PhantomData, diff --git a/crossbeam-epoch/src/epoch.rs b/crossbeam-epoch/src/epoch.rs index 18d7418a1..0c1c99dca 100644 --- a/crossbeam-epoch/src/epoch.rs +++ b/crossbeam-epoch/src/epoch.rs @@ -45,16 +45,16 @@ impl Epoch { /// Returns the same epoch, but marked as pinned. #[inline] - pub(crate) fn pinned(self) -> Epoch { - Epoch { + pub(crate) fn pinned(self) -> Self { + Self { data: self.data | 1, } } /// Returns the same epoch, but marked as unpinned. #[inline] - pub(crate) fn unpinned(self) -> Epoch { - Epoch { + pub(crate) fn unpinned(self) -> Self { + Self { data: self.data & !1, } } @@ -63,8 +63,8 @@ impl Epoch { /// /// The returned epoch will be marked as pinned only if the previous one was as well. #[inline] - pub(crate) fn successor(self) -> Epoch { - Epoch { + pub(crate) fn successor(self) -> Self { + Self { data: self.data.wrapping_add(2), } } @@ -83,7 +83,7 @@ impl AtomicEpoch { #[inline] pub(crate) fn new(epoch: Epoch) -> Self { let data = AtomicUsize::new(epoch.data); - AtomicEpoch { data } + Self { data } } /// Loads a value from the atomic epoch. diff --git a/crossbeam-epoch/src/guard.rs b/crossbeam-epoch/src/guard.rs index da1c5c01b..5fe33807c 100644 --- a/crossbeam-epoch/src/guard.rs +++ b/crossbeam-epoch/src/guard.rs @@ -1,8 +1,6 @@ use core::fmt; use core::mem; -use scopeguard::defer; - use crate::atomic::Shared; use crate::collector::Collector; use crate::deferred::Deferred; @@ -366,6 +364,17 @@ impl Guard { where F: FnOnce() -> R, { + // Ensure the Guard is re-pinned even if the function panics + struct ScopeGuard(*const Local); + impl Drop for ScopeGuard { + fn drop(&mut self) { + if let Some(local) = unsafe { self.0.as_ref() } { + mem::forget(local.pin()); + local.release_handle(); + } + } + } + if let Some(local) = unsafe { self.local.as_ref() } { // We need to acquire a handle here to ensure the Local doesn't // disappear from under us. @@ -373,13 +382,7 @@ impl Guard { local.unpin(); } - // Ensure the Guard is re-pinned even if the function panics - defer! { - if let Some(local) = unsafe { self.local.as_ref() } { - mem::forget(local.pin()); - local.release_handle(); - } - } + let _guard = ScopeGuard(self.local); f() } diff --git a/crossbeam-epoch/src/internal.rs b/crossbeam-epoch/src/internal.rs index 74d64808a..de69a9380 100644 --- a/crossbeam-epoch/src/internal.rs +++ b/crossbeam-epoch/src/internal.rs @@ -107,7 +107,7 @@ impl Bag { impl Default for Bag { fn default() -> Self { - Bag { + Self { len: 0, deferreds: [Deferred::NO_OP; MAX_OBJECTS], } @@ -317,7 +317,7 @@ impl Local { unsafe { // Since we dereference no pointers in this block, it is safe to use `unprotected`. - let local = Owned::new(Local { + let local = Owned::new(Self { entry: Entry::default(), collector: UnsafeCell::new(ManuallyDrop::new(collector.clone())), bag: UnsafeCell::new(Bag::new()), @@ -534,20 +534,20 @@ impl Local { } } -impl IsElement for Local { - fn entry_of(local: &Local) -> &Entry { +impl IsElement for Local { + fn entry_of(local: &Self) -> &Entry { unsafe { - let entry_ptr = (local as *const Local as *const u8) + let entry_ptr = (local as *const Self as *const u8) .add(offset_of!(Local, entry)) .cast::(); &*entry_ptr } } - unsafe fn element_of(entry: &Entry) -> &Local { + unsafe fn element_of(entry: &Entry) -> &Self { let local_ptr = (entry as *const Entry as *const u8) .sub(offset_of!(Local, entry)) - .cast::(); + .cast::(); &*local_ptr } diff --git a/crossbeam-epoch/src/lib.rs b/crossbeam-epoch/src/lib.rs index dff22f133..2fcdb2b1c 100644 --- a/crossbeam-epoch/src/lib.rs +++ b/crossbeam-epoch/src/lib.rs @@ -51,16 +51,11 @@ #![doc(test( no_crate_inject, attr( - deny(warnings, rust_2018_idioms), + deny(warnings, rust_2018_idioms, single_use_lifetimes), allow(dead_code, unused_assignments, unused_variables) ) ))] -#![warn( - missing_docs, - missing_debug_implementations, - rust_2018_idioms, - unreachable_pub -)] +#![warn(missing_docs)] #![cfg_attr(not(feature = "std"), no_std)] #[cfg(crossbeam_loom)] @@ -105,8 +100,8 @@ mod primitive { // https://github.com/tokio-rs/loom#handling-loom-api-differences impl UnsafeCell { #[inline] - pub(crate) const fn new(data: T) -> UnsafeCell { - UnsafeCell(::core::cell::UnsafeCell::new(data)) + pub(crate) const fn new(data: T) -> Self { + Self(::core::cell::UnsafeCell::new(data)) } #[inline] diff --git a/crossbeam-epoch/src/sync/list.rs b/crossbeam-epoch/src/sync/list.rs index 52ffd6fca..b8190b17e 100644 --- a/crossbeam-epoch/src/sync/list.rs +++ b/crossbeam-epoch/src/sync/list.rs @@ -302,12 +302,12 @@ mod tests { use crossbeam_utils::thread; use std::sync::Barrier; - impl IsElement for Entry { - fn entry_of(entry: &Entry) -> &Entry { + impl IsElement for Entry { + fn entry_of(entry: &Self) -> &Entry { entry } - unsafe fn element_of(entry: &Entry) -> &Entry { + unsafe fn element_of(entry: &Entry) -> &Self { entry } diff --git a/crossbeam-epoch/src/sync/queue.rs b/crossbeam-epoch/src/sync/queue.rs index 950043881..cb0215edc 100644 --- a/crossbeam-epoch/src/sync/queue.rs +++ b/crossbeam-epoch/src/sync/queue.rs @@ -42,8 +42,8 @@ unsafe impl Send for Queue {} impl Queue { /// Create a new, empty queue. - pub(crate) fn new() -> Queue { - let q = Queue { + pub(crate) fn new() -> Self { + let q = Self { head: CachePadded::new(Atomic::null()), tail: CachePadded::new(Atomic::null()), }; @@ -226,8 +226,8 @@ mod test { } impl Queue { - pub(crate) fn new() -> Queue { - Queue { + pub(crate) fn new() -> Self { + Self { queue: super::Queue::new(), } } diff --git a/crossbeam-epoch/tests/loom.rs b/crossbeam-epoch/tests/loom.rs index 4e56acdbc..b56531844 100644 --- a/crossbeam-epoch/tests/loom.rs +++ b/crossbeam-epoch/tests/loom.rs @@ -51,7 +51,7 @@ fn treiber_stack() { /// /// Usable with any number of producers and consumers. #[derive(Debug)] - pub struct TreiberStack { + struct TreiberStack { head: Atomic>, } @@ -63,14 +63,14 @@ fn treiber_stack() { impl TreiberStack { /// Creates a new, empty stack. - pub fn new() -> TreiberStack { - TreiberStack { + fn new() -> Self { + Self { head: Atomic::null(), } } /// Pushes a value on top of the stack. - pub fn push(&self, t: T) { + fn push(&self, t: T) { let mut n = Owned::new(Node { data: ManuallyDrop::new(t), next: Atomic::null(), @@ -95,7 +95,7 @@ fn treiber_stack() { /// Attempts to pop the top element from the stack. /// /// Returns `None` if the stack is empty. - pub fn pop(&self) -> Option { + fn pop(&self) -> Option { let guard = epoch::pin(); loop { let head = self.head.load(Acquire, &guard); @@ -121,7 +121,7 @@ fn treiber_stack() { } /// Returns `true` if the stack is empty. - pub fn is_empty(&self) -> bool { + fn is_empty(&self) -> bool { let guard = epoch::pin(); self.head.load(Acquire, &guard).is_null() } diff --git a/crossbeam-queue/Cargo.toml b/crossbeam-queue/Cargo.toml index 09be60e27..842f3b117 100644 --- a/crossbeam-queue/Cargo.toml +++ b/crossbeam-queue/Cargo.toml @@ -5,7 +5,7 @@ name = "crossbeam-queue" # - Update README.md # - Create "crossbeam-queue-X.Y.Z" git tag version = "0.3.8" -edition = "2018" +edition = "2021" rust-version = "1.61" license = "MIT OR Apache-2.0" repository = "https://github.com/crossbeam-rs/crossbeam" @@ -37,3 +37,6 @@ default-features = false [dev-dependencies] rand = "0.8" + +[lints] +workspace = true diff --git a/crossbeam-queue/src/array_queue.rs b/crossbeam-queue/src/array_queue.rs index 2b7936d9d..a76d4f3e9 100644 --- a/crossbeam-queue/src/array_queue.rs +++ b/crossbeam-queue/src/array_queue.rs @@ -90,7 +90,7 @@ impl ArrayQueue { /// /// let q = ArrayQueue::::new(100); /// ``` - pub fn new(cap: usize) -> ArrayQueue { + pub fn new(cap: usize) -> Self { assert!(cap > 0, "capacity must be non-zero"); // Head is initialized to `{ lap: 0, index: 0 }`. @@ -113,7 +113,7 @@ impl ArrayQueue { // One lap is the smallest power of two greater than `cap`. let one_lap = (cap + 1).next_power_of_two(); - ArrayQueue { + Self { buffer, cap, one_lap, diff --git a/crossbeam-queue/src/lib.rs b/crossbeam-queue/src/lib.rs index 36687282a..5c27f388a 100644 --- a/crossbeam-queue/src/lib.rs +++ b/crossbeam-queue/src/lib.rs @@ -8,16 +8,11 @@ #![doc(test( no_crate_inject, attr( - deny(warnings, rust_2018_idioms), + deny(warnings, rust_2018_idioms, single_use_lifetimes), allow(dead_code, unused_assignments, unused_variables) ) ))] -#![warn( - missing_docs, - missing_debug_implementations, - rust_2018_idioms, - unreachable_pub -)] +#![warn(missing_docs)] #![cfg_attr(not(feature = "std"), no_std)] #[cfg(target_has_atomic = "ptr")] diff --git a/crossbeam-queue/src/seg_queue.rs b/crossbeam-queue/src/seg_queue.rs index 2761dc07c..9d660829c 100644 --- a/crossbeam-queue/src/seg_queue.rs +++ b/crossbeam-queue/src/seg_queue.rs @@ -62,7 +62,7 @@ struct Block { impl Block { /// Creates an empty block that starts at `start_index`. - fn new() -> Block { + fn new() -> Self { Self { next: AtomicPtr::new(ptr::null_mut()), slots: [Slot::UNINIT; BLOCK_CAP], @@ -70,7 +70,7 @@ impl Block { } /// Waits until the next pointer is set. - fn wait_next(&self) -> *mut Block { + fn wait_next(&self) -> *mut Self { let backoff = Backoff::new(); loop { let next = self.next.load(Ordering::Acquire); @@ -82,7 +82,7 @@ impl Block { } /// Sets the `DESTROY` bit in slots starting from `start` and destroys the block. - unsafe fn destroy(this: *mut Block, start: usize) { + unsafe fn destroy(this: *mut Self, start: usize) { // It is not necessary to set the `DESTROY` bit in the last slot because that slot has // begun destruction of the block. for i in start..BLOCK_CAP - 1 { @@ -158,8 +158,8 @@ impl SegQueue { /// /// let q = SegQueue::::new(); /// ``` - pub const fn new() -> SegQueue { - SegQueue { + pub const fn new() -> Self { + Self { head: CachePadded::new(Position { block: AtomicPtr::new(ptr::null_mut()), index: AtomicUsize::new(0), @@ -482,8 +482,8 @@ impl fmt::Debug for SegQueue { } impl Default for SegQueue { - fn default() -> SegQueue { - SegQueue::new() + fn default() -> Self { + Self::new() } } diff --git a/crossbeam-skiplist/Cargo.toml b/crossbeam-skiplist/Cargo.toml index 776c558ff..cbf524087 100644 --- a/crossbeam-skiplist/Cargo.toml +++ b/crossbeam-skiplist/Cargo.toml @@ -5,7 +5,7 @@ name = "crossbeam-skiplist" # - Update README.md # - Create "crossbeam-skiplist-X.Y.Z" git tag version = "0.1.1" -edition = "2018" +edition = "2021" rust-version = "1.61" license = "MIT OR Apache-2.0" repository = "https://github.com/crossbeam-rs/crossbeam" @@ -41,9 +41,8 @@ version = "0.8.5" path = "../crossbeam-utils" default-features = false -[dependencies.scopeguard] -version = "1.1.0" -default-features = false - [dev-dependencies] rand = "0.8" + +[lints] +workspace = true diff --git a/crossbeam-skiplist/src/base.rs b/crossbeam-skiplist/src/base.rs index 525af1b1c..f8e26c496 100644 --- a/crossbeam-skiplist/src/base.rs +++ b/crossbeam-skiplist/src/base.rs @@ -52,9 +52,9 @@ struct Head { impl Head { /// Initializes a `Head`. #[inline] - fn new() -> Head { + fn new() -> Self { // Initializing arrays in rust is a pain... - Head { + Self { pointers: Default::default(), } } @@ -256,7 +256,7 @@ impl Node { ptr::drop_in_place(&mut (*ptr).value); // Finally, deallocate the memory occupied by the node. - Node::dealloc(ptr); + Self::dealloc(ptr); } } @@ -332,8 +332,8 @@ unsafe impl Sync for SkipList {} impl SkipList { /// Returns a new, empty skip list. - pub fn new(collector: Collector) -> SkipList { - SkipList { + pub fn new(collector: Collector) -> Self { + Self { head: Head::new(), collector, hot_data: CachePadded::new(HotData { @@ -937,9 +937,13 @@ where // We failed. Let's search for the key and try again. { // Create a guard that destroys the new node in case search panics. - let sg = scopeguard::guard((), |_| { - Node::finalize(node.as_raw()); - }); + struct ScopeGuard(*const Node); + impl Drop for ScopeGuard { + fn drop(&mut self) { + unsafe { Node::finalize(self.0) } + } + } + let sg = ScopeGuard(node.as_raw()); search = self.search_position(&n.key, guard); mem::forget(sg); } @@ -1345,7 +1349,7 @@ impl<'a: 'g, 'g, K: 'a, V: 'a> Entry<'a, 'g, K, V> { } } -impl<'a: 'g, 'g, K, V> Entry<'a, 'g, K, V> +impl Entry<'_, '_, K, V> where K: Ord + Send + 'static, V: Send + 'static, @@ -1370,9 +1374,9 @@ where } } -impl<'a: 'g, 'g, K, V> Clone for Entry<'a, 'g, K, V> { - fn clone(&self) -> Entry<'a, 'g, K, V> { - Entry { +impl Clone for Entry<'_, '_, K, V> { + fn clone(&self) -> Self { + Self { parent: self.parent, node: self.node, guard: self.guard, @@ -1538,13 +1542,13 @@ where } } -impl<'a, K, V> Clone for RefEntry<'a, K, V> { - fn clone(&self) -> RefEntry<'a, K, V> { +impl Clone for RefEntry<'_, K, V> { + fn clone(&self) -> Self { unsafe { // Incrementing will always succeed since we're already holding a reference to the node. Node::try_increment(self.node); } - RefEntry { + Self { parent: self.parent, node: self.node, } diff --git a/crossbeam-skiplist/src/lib.rs b/crossbeam-skiplist/src/lib.rs index 194823800..c632f6eb8 100644 --- a/crossbeam-skiplist/src/lib.rs +++ b/crossbeam-skiplist/src/lib.rs @@ -231,16 +231,11 @@ #![doc(test( no_crate_inject, attr( - deny(warnings, rust_2018_idioms), + deny(warnings, rust_2018_idioms, single_use_lifetimes), allow(dead_code, unused_assignments, unused_variables) ) ))] -#![warn( - missing_docs, - missing_debug_implementations, - rust_2018_idioms, - unreachable_pub -)] +#![warn(missing_docs)] #![cfg_attr(not(feature = "std"), no_std)] use cfg_if::cfg_if; diff --git a/crossbeam-skiplist/src/map.rs b/crossbeam-skiplist/src/map.rs index 9a72de227..682492090 100644 --- a/crossbeam-skiplist/src/map.rs +++ b/crossbeam-skiplist/src/map.rs @@ -2,7 +2,6 @@ use std::borrow::Borrow; use std::fmt; -use std::iter::FromIterator; use std::mem::ManuallyDrop; use std::ops::{Bound, RangeBounds}; use std::ptr; @@ -30,8 +29,8 @@ impl SkipMap { /// /// let map: SkipMap = SkipMap::new(); /// ``` - pub fn new() -> SkipMap { - SkipMap { + pub fn new() -> Self { + Self { inner: base::SkipList::new(epoch::default_collector().clone()), } } @@ -506,8 +505,8 @@ where } impl Default for SkipMap { - fn default() -> SkipMap { - SkipMap::new() + fn default() -> Self { + Self::new() } } @@ -548,11 +547,11 @@ impl FromIterator<(K, V)> for SkipMap where K: Ord, { - fn from_iter(iter: I) -> SkipMap + fn from_iter(iter: I) -> Self where I: IntoIterator, { - let s = SkipMap::new(); + let s = Self::new(); for (k, v) in iter { s.get_or_insert(k, v); } @@ -566,8 +565,8 @@ pub struct Entry<'a, K, V> { } impl<'a, K, V> Entry<'a, K, V> { - fn new(inner: base::RefEntry<'a, K, V>) -> Entry<'a, K, V> { - Entry { + fn new(inner: base::RefEntry<'a, K, V>) -> Self { + Self { inner: ManuallyDrop::new(inner), } } @@ -639,9 +638,9 @@ where } } -impl<'a, K, V> Clone for Entry<'a, K, V> { - fn clone(&self) -> Entry<'a, K, V> { - Entry { +impl Clone for Entry<'_, K, V> { + fn clone(&self) -> Self { + Self { inner: self.inner.clone(), } } @@ -712,7 +711,7 @@ impl fmt::Debug for Iter<'_, K, V> { } } -impl<'a, K, V> Drop for Iter<'a, K, V> { +impl Drop for Iter<'_, K, V> { fn drop(&mut self) { let guard = &epoch::pin(); self.inner.drop_impl(guard); diff --git a/crossbeam-skiplist/src/set.rs b/crossbeam-skiplist/src/set.rs index cc4083472..3093ae4aa 100644 --- a/crossbeam-skiplist/src/set.rs +++ b/crossbeam-skiplist/src/set.rs @@ -2,7 +2,6 @@ use std::borrow::Borrow; use std::fmt; -use std::iter::FromIterator; use std::ops::Deref; use std::ops::{Bound, RangeBounds}; @@ -28,8 +27,8 @@ impl SkipSet { /// /// let set: SkipSet = SkipSet::new(); /// ``` - pub fn new() -> SkipSet { - SkipSet { + pub fn new() -> Self { + Self { inner: map::SkipMap::new(), } } @@ -392,8 +391,8 @@ where } impl Default for SkipSet { - fn default() -> SkipSet { - SkipSet::new() + fn default() -> Self { + Self::new() } } @@ -433,11 +432,11 @@ impl FromIterator for SkipSet where T: Ord, { - fn from_iter(iter: I) -> SkipSet + fn from_iter(iter: I) -> Self where I: IntoIterator, { - let s = SkipSet::new(); + let s = Self::new(); for t in iter { s.get_or_insert(t); } @@ -451,8 +450,8 @@ pub struct Entry<'a, T> { } impl<'a, T> Entry<'a, T> { - fn new(inner: map::Entry<'a, T, ()>) -> Entry<'a, T> { - Entry { inner } + fn new(inner: map::Entry<'a, T, ()>) -> Self { + Self { inner } } /// Returns a reference to the value. @@ -503,9 +502,9 @@ where } } -impl<'a, T> Clone for Entry<'a, T> { - fn clone(&self) -> Entry<'a, T> { - Entry { +impl Clone for Entry<'_, T> { + fn clone(&self) -> Self { + Self { inner: self.inner.clone(), } } diff --git a/crossbeam-utils/Cargo.toml b/crossbeam-utils/Cargo.toml index 8e3156cdd..1b30a1db3 100644 --- a/crossbeam-utils/Cargo.toml +++ b/crossbeam-utils/Cargo.toml @@ -5,7 +5,7 @@ name = "crossbeam-utils" # - Update README.md # - Create "crossbeam-utils-X.Y.Z" git tag version = "0.8.16" -edition = "2018" +edition = "2021" rust-version = "1.61" license = "MIT OR Apache-2.0" repository = "https://github.com/crossbeam-rs/crossbeam" @@ -33,3 +33,6 @@ loom = { version = "0.7.1", optional = true } [dev-dependencies] rand = "0.8" + +[lints] +workspace = true diff --git a/crossbeam-utils/build.rs b/crossbeam-utils/build.rs index c71c23136..827d22310 100644 --- a/crossbeam-utils/build.rs +++ b/crossbeam-utils/build.rs @@ -10,8 +10,6 @@ // With the exceptions mentioned above, the rustc-cfg emitted by the build // script are *not* public API. -#![warn(rust_2018_idioms)] - use std::env; include!("no_atomic.rs"); diff --git a/crossbeam-utils/src/atomic/atomic_cell.rs b/crossbeam-utils/src/atomic/atomic_cell.rs index 6ce11fc76..255271909 100644 --- a/crossbeam-utils/src/atomic/atomic_cell.rs +++ b/crossbeam-utils/src/atomic/atomic_cell.rs @@ -6,12 +6,9 @@ use core::cell::UnsafeCell; use core::cmp; use core::fmt; use core::mem::{self, ManuallyDrop, MaybeUninit}; - +use core::panic::{RefUnwindSafe, UnwindSafe}; use core::ptr; -#[cfg(feature = "std")] -use std::panic::{RefUnwindSafe, UnwindSafe}; - use super::seq_lock::SeqLock; /// A thread-safe mutable memory location. @@ -48,9 +45,7 @@ pub struct AtomicCell { unsafe impl Send for AtomicCell {} unsafe impl Sync for AtomicCell {} -#[cfg(feature = "std")] impl UnwindSafe for AtomicCell {} -#[cfg(feature = "std")] impl RefUnwindSafe for AtomicCell {} impl AtomicCell { @@ -63,8 +58,8 @@ impl AtomicCell { /// /// let a = AtomicCell::new(7); /// ``` - pub const fn new(val: T) -> AtomicCell { - AtomicCell { + pub const fn new(val: T) -> Self { + Self { value: UnsafeCell::new(MaybeUninit::new(val)), } } @@ -916,15 +911,15 @@ impl AtomicCell { } impl Default for AtomicCell { - fn default() -> AtomicCell { - AtomicCell::new(T::default()) + fn default() -> Self { + Self::new(T::default()) } } impl From for AtomicCell { #[inline] - fn from(val: T) -> AtomicCell { - AtomicCell::new(val) + fn from(val: T) -> Self { + Self::new(val) } } diff --git a/crossbeam-utils/src/backoff.rs b/crossbeam-utils/src/backoff.rs index bd85dc607..9729ce695 100644 --- a/crossbeam-utils/src/backoff.rs +++ b/crossbeam-utils/src/backoff.rs @@ -93,7 +93,7 @@ impl Backoff { /// ``` #[inline] pub fn new() -> Self { - Backoff { step: Cell::new(0) } + Self { step: Cell::new(0) } } /// Resets the `Backoff`. @@ -283,7 +283,7 @@ impl fmt::Debug for Backoff { } impl Default for Backoff { - fn default() -> Backoff { - Backoff::new() + fn default() -> Self { + Self::new() } } diff --git a/crossbeam-utils/src/cache_padded.rs b/crossbeam-utils/src/cache_padded.rs index f44f2d7b4..cf6ebfc45 100644 --- a/crossbeam-utils/src/cache_padded.rs +++ b/crossbeam-utils/src/cache_padded.rs @@ -160,8 +160,8 @@ impl CachePadded { /// /// let padded_value = CachePadded::new(1); /// ``` - pub const fn new(t: T) -> CachePadded { - CachePadded:: { value: t } + pub const fn new(t: T) -> Self { + Self { value: t } } /// Returns the inner value. @@ -204,6 +204,6 @@ impl fmt::Debug for CachePadded { impl From for CachePadded { fn from(t: T) -> Self { - CachePadded::new(t) + Self::new(t) } } diff --git a/crossbeam-utils/src/lib.rs b/crossbeam-utils/src/lib.rs index 6ab748f34..86a9ac540 100644 --- a/crossbeam-utils/src/lib.rs +++ b/crossbeam-utils/src/lib.rs @@ -27,16 +27,11 @@ #![doc(test( no_crate_inject, attr( - deny(warnings, rust_2018_idioms), + deny(warnings, rust_2018_idioms, single_use_lifetimes), allow(dead_code, unused_assignments, unused_variables) ) ))] -#![warn( - missing_docs, - missing_debug_implementations, - rust_2018_idioms, - unreachable_pub -)] +#![warn(missing_docs)] #![cfg_attr(not(feature = "std"), no_std)] #[cfg(crossbeam_loom)] diff --git a/crossbeam-utils/src/sync/parker.rs b/crossbeam-utils/src/sync/parker.rs index 399e1629c..5d6e2bc59 100644 --- a/crossbeam-utils/src/sync/parker.rs +++ b/crossbeam-utils/src/sync/parker.rs @@ -84,7 +84,7 @@ impl Parker { /// let p = Parker::new(); /// ``` /// - pub fn new() -> Parker { + pub fn new() -> Self { Self::default() } @@ -184,7 +184,7 @@ impl Parker { /// let raw = Parker::into_raw(p); /// # let _ = unsafe { Parker::from_raw(raw) }; /// ``` - pub fn into_raw(this: Parker) -> *const () { + pub fn into_raw(this: Self) -> *const () { Unparker::into_raw(this.unparker) } @@ -203,8 +203,8 @@ impl Parker { /// let raw = Parker::into_raw(p); /// let p = unsafe { Parker::from_raw(raw) }; /// ``` - pub unsafe fn from_raw(ptr: *const ()) -> Parker { - Parker { + pub unsafe fn from_raw(ptr: *const ()) -> Self { + Self { unparker: Unparker::from_raw(ptr), _marker: PhantomData, } @@ -270,7 +270,7 @@ impl Unparker { /// let raw = Unparker::into_raw(u); /// # let _ = unsafe { Unparker::from_raw(raw) }; /// ``` - pub fn into_raw(this: Unparker) -> *const () { + pub fn into_raw(this: Self) -> *const () { Arc::into_raw(this.inner).cast::<()>() } @@ -291,8 +291,8 @@ impl Unparker { /// let raw = Unparker::into_raw(u); /// let u = unsafe { Unparker::from_raw(raw) }; /// ``` - pub unsafe fn from_raw(ptr: *const ()) -> Unparker { - Unparker { + pub unsafe fn from_raw(ptr: *const ()) -> Self { + Self { inner: Arc::from_raw(ptr.cast::()), } } @@ -305,8 +305,8 @@ impl fmt::Debug for Unparker { } impl Clone for Unparker { - fn clone(&self) -> Unparker { - Unparker { + fn clone(&self) -> Self { + Self { inner: self.inner.clone(), } } diff --git a/crossbeam-utils/src/sync/sharded_lock.rs b/crossbeam-utils/src/sync/sharded_lock.rs index b97ace639..7bdcbd7f4 100644 --- a/crossbeam-utils/src/sync/sharded_lock.rs +++ b/crossbeam-utils/src/sync/sharded_lock.rs @@ -97,8 +97,8 @@ impl ShardedLock { /// /// let lock = ShardedLock::new(5); /// ``` - pub fn new(value: T) -> ShardedLock { - ShardedLock { + pub fn new(value: T) -> Self { + Self { shards: (0..NUM_SHARDS) .map(|_| { CachePadded::new(Shard { @@ -468,14 +468,14 @@ impl fmt::Debug for ShardedLock { } impl Default for ShardedLock { - fn default() -> ShardedLock { - ShardedLock::new(Default::default()) + fn default() -> Self { + Self::new(Default::default()) } } impl From for ShardedLock { fn from(t: T) -> Self { - ShardedLock::new(t) + Self::new(t) } } diff --git a/crossbeam-utils/src/sync/wait_group.rs b/crossbeam-utils/src/sync/wait_group.rs index b50707b50..3c55fac63 100644 --- a/crossbeam-utils/src/sync/wait_group.rs +++ b/crossbeam-utils/src/sync/wait_group.rs @@ -128,11 +128,11 @@ impl Drop for WaitGroup { } impl Clone for WaitGroup { - fn clone(&self) -> WaitGroup { + fn clone(&self) -> Self { let mut count = self.inner.count.lock().unwrap(); *count += 1; - WaitGroup { + Self { inner: self.inner.clone(), } } diff --git a/crossbeam-utils/src/thread.rs b/crossbeam-utils/src/thread.rs index 71856ebe5..7b1c45a05 100644 --- a/crossbeam-utils/src/thread.rs +++ b/crossbeam-utils/src/thread.rs @@ -84,7 +84,7 @@ //! tricky because argument `s` lives *inside* the invocation of `thread::scope()` and as such //! cannot be borrowed by scoped threads: //! -//! ```compile_fail,E0373,E0521 +//! ```compile_fail,E0521 //! use crossbeam_utils::thread; //! //! thread::scope(|s| { @@ -151,6 +151,15 @@ pub fn scope<'env, F, R>(f: F) -> thread::Result where F: FnOnce(&Scope<'env>) -> R, { + struct AbortOnPanic; + impl Drop for AbortOnPanic { + fn drop(&mut self) { + if thread::panicking() { + std::process::abort(); + } + } + } + let wg = WaitGroup::new(); let scope = Scope::<'env> { handles: SharedVec::default(), @@ -161,6 +170,10 @@ where // Execute the scoped function, but catch any panics. let result = panic::catch_unwind(panic::AssertUnwindSafe(|| f(&scope))); + // If an unwinding panic occurs before all threads are joined + // promote it to an aborting panic to prevent any threads from escaping the scope. + let guard = AbortOnPanic; + // Wait until all nested scopes are dropped. drop(scope.wait_group); wg.wait(); @@ -176,6 +189,8 @@ where .filter_map(|handle| handle.join().err()) .collect(); + mem::forget(guard); + // If `f` has panicked, resume unwinding. // If any of the child threads have panicked, return the panic errors. // Otherwise, everything is OK and return the result of `f`. diff --git a/crossbeam-utils/tests/atomic_cell.rs b/crossbeam-utils/tests/atomic_cell.rs index 3b76db5ba..16ee815cb 100644 --- a/crossbeam-utils/tests/atomic_cell.rs +++ b/crossbeam-utils/tests/atomic_cell.rs @@ -63,9 +63,9 @@ fn drops_unit() { struct Foo(); impl Foo { - fn new() -> Foo { + fn new() -> Self { CNT.fetch_add(1, SeqCst); - Foo() + Self() } } @@ -76,8 +76,8 @@ fn drops_unit() { } impl Default for Foo { - fn default() -> Foo { - Foo::new() + fn default() -> Self { + Self::new() } } @@ -105,9 +105,9 @@ fn drops_u8() { struct Foo(u8); impl Foo { - fn new(val: u8) -> Foo { + fn new(val: u8) -> Self { CNT.fetch_add(1, SeqCst); - Foo(val) + Self(val) } } @@ -118,8 +118,8 @@ fn drops_u8() { } impl Default for Foo { - fn default() -> Foo { - Foo::new(0) + fn default() -> Self { + Self::new(0) } } @@ -151,9 +151,9 @@ fn drops_usize() { struct Foo(usize); impl Foo { - fn new(val: usize) -> Foo { + fn new(val: usize) -> Self { CNT.fetch_add(1, SeqCst); - Foo(val) + Self(val) } } @@ -164,8 +164,8 @@ fn drops_usize() { } impl Default for Foo { - fn default() -> Foo { - Foo::new(0) + fn default() -> Self { + Self::new(0) } } @@ -194,7 +194,7 @@ fn modular_u8() { struct Foo(u8); impl PartialEq for Foo { - fn eq(&self, other: &Foo) -> bool { + fn eq(&self, other: &Self) -> bool { self.0 % 5 == other.0 % 5 } } @@ -218,7 +218,7 @@ fn modular_usize() { struct Foo(usize); impl PartialEq for Foo { - fn eq(&self, other: &Foo) -> bool { + fn eq(&self, other: &Self) -> bool { self.0 % 5 == other.0 % 5 } } diff --git a/crossbeam-utils/tests/cache_padded.rs b/crossbeam-utils/tests/cache_padded.rs index 86e9a7709..7e5df215c 100644 --- a/crossbeam-utils/tests/cache_padded.rs +++ b/crossbeam-utils/tests/cache_padded.rs @@ -69,7 +69,7 @@ fn drops() { struct Foo<'a>(&'a Cell); - impl<'a> Drop for Foo<'a> { + impl Drop for Foo<'_> { fn drop(&mut self) { self.0.set(self.0.get() + 1); } @@ -99,10 +99,10 @@ fn runs_custom_clone() { struct Foo<'a>(&'a Cell); - impl<'a> Clone for Foo<'a> { - fn clone(&self) -> Foo<'a> { + impl Clone for Foo<'_> { + fn clone(&self) -> Self { self.0.set(self.0.get() + 1); - Foo::<'a>(self.0) + Self(self.0) } } diff --git a/src/lib.rs b/src/lib.rs index 9bc3ec111..204bd22e1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -41,16 +41,11 @@ #![doc(test( no_crate_inject, attr( - deny(warnings, rust_2018_idioms), + deny(warnings, rust_2018_idioms, single_use_lifetimes), allow(dead_code, unused_assignments, unused_variables) ) ))] -#![warn( - missing_docs, - missing_debug_implementations, - rust_2018_idioms, - unreachable_pub -)] +#![warn(missing_docs)] #![cfg_attr(not(feature = "std"), no_std)] pub use crossbeam_utils::atomic;