Fix clippy lints

This commit is contained in:
Alex Martens 2023-11-15 13:20:54 -08:00
parent ee14cda7ff
commit d7306dbbd2
15 changed files with 120 additions and 66 deletions

View File

@ -101,6 +101,18 @@ jobs:
- name: cargo fmt --check - name: cargo fmt --check
run: cargo fmt --all -- --check run: cargo fmt --all -- --check
clippy:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
components: clippy
targets: i686-unknown-linux-gnu
- run: cargo clippy --all --target i686-unknown-linux-gnu -- --deny warnings
# Compilation check # Compilation check
check: check:
name: check name: check

View File

@ -7,7 +7,13 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
## [Unreleased] ## [Unreleased]
- configure `stable_deref_trait` as a platform-dependent dependency ### Changed
- Changed `stable_deref_trait` to a platform-dependent dependency.
### Fixed
- Fixed clippy lints.
## [v0.8.0] - 2023-11-07 ## [v0.8.0] - 2023-11-07

View File

@ -233,7 +233,7 @@ where
/// assert_eq!(heap.peek(), Some(&5)); /// assert_eq!(heap.peek(), Some(&5));
/// ``` /// ```
pub fn peek(&self) -> Option<&T> { pub fn peek(&self) -> Option<&T> {
self.data.as_slice().get(0) self.data.as_slice().first()
} }
/// Returns a mutable reference to the greatest item in the binary heap, or /// Returns a mutable reference to the greatest item in the binary heap, or
@ -297,6 +297,7 @@ where
/// Removes the *top* (greatest if max-heap, smallest if min-heap) item from the binary heap and /// Removes the *top* (greatest if max-heap, smallest if min-heap) item from the binary heap and
/// returns it, without checking if the binary heap is empty. /// returns it, without checking if the binary heap is empty.
#[allow(clippy::missing_safety_doc)] // TODO
pub unsafe fn pop_unchecked(&mut self) -> T { pub unsafe fn pop_unchecked(&mut self) -> T {
let mut item = self.data.pop_unchecked(); let mut item = self.data.pop_unchecked();
@ -330,6 +331,7 @@ where
} }
/// Pushes an item onto the binary heap without first checking if it's full. /// Pushes an item onto the binary heap without first checking if it's full.
#[allow(clippy::missing_safety_doc)] // TODO
pub unsafe fn push_unchecked(&mut self, item: T) { pub unsafe fn push_unchecked(&mut self, item: T) {
let old_len = self.len(); let old_len = self.len();
self.data.push_unchecked(item); self.data.push_unchecked(item);

View File

@ -283,7 +283,7 @@ impl<T, const N: usize> Deque<T, N> {
let index = self.front; let index = self.front;
self.full = false; self.full = false;
self.front = Self::increment(self.front); self.front = Self::increment(self.front);
(self.buffer.get_unchecked_mut(index).as_ptr() as *const T).read() self.buffer.get_unchecked_mut(index).as_ptr().read()
} }
/// Removes an item from the back of the deque and returns it, without checking that the deque /// Removes an item from the back of the deque and returns it, without checking that the deque
@ -297,7 +297,7 @@ impl<T, const N: usize> Deque<T, N> {
self.full = false; self.full = false;
self.back = Self::decrement(self.back); self.back = Self::decrement(self.back);
(self.buffer.get_unchecked_mut(self.back).as_ptr() as *const T).read() self.buffer.get_unchecked_mut(self.back).as_ptr().read()
} }
/// Appends an `item` to the front of the deque /// Appends an `item` to the front of the deque

View File

@ -117,6 +117,21 @@ impl<T, const N: usize> HistoryBuffer<T, N> {
} }
} }
/// Returns true if the buffer is empty.
///
/// # Examples
///
/// ```
/// use heapless::HistoryBuffer;
///
/// let x: HistoryBuffer<u8, 16> = HistoryBuffer::new();
/// assert!(x.is_empty());
/// ```
#[inline]
pub fn is_empty(&self) -> bool {
self.len() == 0
}
/// Returns the capacity of the buffer, which is the length of the /// Returns the capacity of the buffer, which is the length of the
/// underlying backing array. /// underlying backing array.
#[inline] #[inline]
@ -219,7 +234,7 @@ impl<T, const N: usize> HistoryBuffer<T, N> {
/// } /// }
/// ///
/// ``` /// ```
pub fn oldest_ordered<'a>(&'a self) -> OldestOrdered<'a, T, N> { pub fn oldest_ordered(&self) -> OldestOrdered<'_, T, N> {
if self.filled { if self.filled {
OldestOrdered { OldestOrdered {
buf: self, buf: self,

View File

@ -1,7 +1,7 @@
use core::{ use core::{
borrow::Borrow, borrow::Borrow,
fmt, fmt,
hash::{BuildHasher, Hash, Hasher as _}, hash::{BuildHasher, Hash},
iter::FromIterator, iter::FromIterator,
mem, mem,
num::NonZeroU32, num::NonZeroU32,
@ -64,7 +64,7 @@ impl HashValue {
} }
fn probe_distance(&self, mask: usize, current: usize) -> usize { fn probe_distance(&self, mask: usize, current: usize) -> usize {
current.wrapping_sub(self.desired_pos(mask) as usize) & mask current.wrapping_sub(self.desired_pos(mask)) & mask
} }
} }
@ -364,7 +364,7 @@ where
fn clone(&self) -> Self { fn clone(&self) -> Self {
Self { Self {
entries: self.entries.clone(), entries: self.entries.clone(),
indices: self.indices.clone(), indices: self.indices,
} }
} }
} }
@ -961,7 +961,7 @@ where
K: Borrow<Q>, K: Borrow<Q>,
Q: ?Sized + Hash + Eq, Q: ?Sized + Hash + Eq,
{ {
if self.len() == 0 { if self.is_empty() {
return None; return None;
} }
let h = hash_with(key, &self.build_hasher); let h = hash_with(key, &self.build_hasher);
@ -1238,9 +1238,7 @@ where
K: ?Sized + Hash, K: ?Sized + Hash,
S: BuildHasher, S: BuildHasher,
{ {
let mut h = build_hasher.build_hasher(); HashValue(build_hasher.hash_one(key) as u16)
key.hash(&mut h);
HashValue(h.finish() as u16)
} }
#[cfg(test)] #[cfg(test)]

View File

@ -448,6 +448,7 @@ pub struct Iter<'a, K, V> {
impl<'a, K, V> Iterator for Iter<'a, K, V> { impl<'a, K, V> Iterator for Iter<'a, K, V> {
type Item = (&'a K, &'a V); type Item = (&'a K, &'a V);
#[allow(clippy::needless_borrowed_reference)]
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
self.iter.next().map(|&(ref k, ref v)| (k, v)) self.iter.next().map(|&(ref k, ref v)| (k, v))
} }

View File

@ -145,7 +145,8 @@ impl<T, const N: usize> MpMcQueue<T, N> {
crate::sealed::power_of_two::<N>(); crate::sealed::power_of_two::<N>();
// Const assert on size. // Const assert on size.
Self::ASSERT[!(N < (IntSize::MAX as usize)) as usize]; #[allow(clippy::no_effect)]
Self::ASSERT[(N >= (IntSize::MAX as usize)) as usize];
let mut cell_count = 0; let mut cell_count = 0;
@ -204,6 +205,7 @@ impl<T> Cell<T> {
} }
} }
#[allow(clippy::comparison_chain)]
unsafe fn dequeue<T>( unsafe fn dequeue<T>(
buffer: *mut Cell<T>, buffer: *mut Cell<T>,
dequeue_pos: &AtomicTargetSize, dequeue_pos: &AtomicTargetSize,
@ -243,6 +245,7 @@ unsafe fn dequeue<T>(
Some(data) Some(data)
} }
#[allow(clippy::comparison_chain)]
unsafe fn enqueue<T>( unsafe fn enqueue<T>(
buffer: *mut Cell<T>, buffer: *mut Cell<T>,
enqueue_pos: &AtomicTargetSize, enqueue_pos: &AtomicTargetSize,

View File

@ -221,7 +221,7 @@ where
P: ArcPool, P: ArcPool,
{ {
fn as_ref(&self) -> &P::Data { fn as_ref(&self) -> &P::Data {
&**self self
} }
} }

View File

@ -1,29 +1,24 @@
#[allow(dead_code)] #[allow(dead_code, path_statements, clippy::no_effect)]
#[allow(path_statements)]
pub(crate) const fn smaller_than<const N: usize, const MAX: usize>() { pub(crate) const fn smaller_than<const N: usize, const MAX: usize>() {
Assert::<N, MAX>::LESS; Assert::<N, MAX>::LESS;
} }
#[allow(dead_code)] #[allow(dead_code, path_statements, clippy::no_effect)]
#[allow(path_statements)]
pub(crate) const fn greater_than_eq_0<const N: usize>() { pub(crate) const fn greater_than_eq_0<const N: usize>() {
Assert::<N, 0>::GREATER_EQ; Assert::<N, 0>::GREATER_EQ;
} }
#[allow(dead_code)] #[allow(dead_code, path_statements, clippy::no_effect)]
#[allow(path_statements)]
pub(crate) const fn greater_than_0<const N: usize>() { pub(crate) const fn greater_than_0<const N: usize>() {
Assert::<N, 0>::GREATER; Assert::<N, 0>::GREATER;
} }
#[allow(dead_code)] #[allow(dead_code, path_statements, clippy::no_effect)]
#[allow(path_statements)]
pub(crate) const fn greater_than_1<const N: usize>() { pub(crate) const fn greater_than_1<const N: usize>() {
Assert::<N, 1>::GREATER; Assert::<N, 1>::GREATER;
} }
#[allow(dead_code)] #[allow(dead_code, path_statements, clippy::no_effect)]
#[allow(path_statements)]
pub(crate) const fn power_of_two<const N: usize>() { pub(crate) const fn power_of_two<const N: usize>() {
Assert::<N, 0>::GREATER; Assert::<N, 0>::GREATER;
Assert::<N, 0>::POWER_OF_TWO; Assert::<N, 0>::POWER_OF_TWO;
@ -42,6 +37,7 @@ impl<const L: usize, const R: usize> Assert<L, R> {
pub const LESS_EQ: usize = R - L; pub const LESS_EQ: usize = R - L;
/// Const assert hack /// Const assert hack
#[allow(clippy::erasing_op)]
pub const NOT_EQ: isize = 0 / (R as isize - L as isize); pub const NOT_EQ: isize = 0 / (R as isize - L as isize);
/// Const assert hack /// Const assert hack

View File

@ -310,7 +310,8 @@ where
/// ``` /// ```
pub fn push(&mut self, value: T) -> Result<(), T> { pub fn push(&mut self, value: T) -> Result<(), T> {
if !self.is_full() { if !self.is_full() {
Ok(unsafe { self.push_unchecked(value) }) unsafe { self.push_unchecked(value) }
Ok(())
} else { } else {
Err(value) Err(value)
} }
@ -462,6 +463,7 @@ where
/// assert_eq!(ll.pop(), Ok(1)); /// assert_eq!(ll.pop(), Ok(1));
/// assert_eq!(ll.pop(), Err(())); /// assert_eq!(ll.pop(), Err(()));
/// ``` /// ```
#[allow(clippy::result_unit_err)]
pub fn pop(&mut self) -> Result<T, ()> { pub fn pop(&mut self) -> Result<T, ()> {
if !self.is_empty() { if !self.is_empty() {
Ok(unsafe { self.pop_unchecked() }) Ok(unsafe { self.pop_unchecked() })

View File

@ -251,7 +251,7 @@ impl<T, const N: usize> Queue<T, N> {
/// Adds an `item` to the end of the queue, without checking if it's full /// Adds an `item` to the end of the queue, without checking if it's full
/// ///
/// # Unsafety /// # Safety
/// ///
/// If the queue is full this operation will leak a value (T's destructor won't run on /// If the queue is full this operation will leak a value (T's destructor won't run on
/// the value that got overwritten by `item`), *and* will allow the `dequeue` operation /// the value that got overwritten by `item`), *and* will allow the `dequeue` operation
@ -295,7 +295,7 @@ impl<T, const N: usize> Queue<T, N> {
/// Returns the item in the front of the queue, without checking if there is something in the /// Returns the item in the front of the queue, without checking if there is something in the
/// queue /// queue
/// ///
/// # Unsafety /// # Safety
/// ///
/// If the queue is empty this operation will return uninitialized memory. /// If the queue is empty this operation will return uninitialized memory.
pub unsafe fn dequeue_unchecked(&mut self) -> T { pub unsafe fn dequeue_unchecked(&mut self) -> T {
@ -507,7 +507,9 @@ impl<'a, T, const N: usize> Consumer<'a, T, N> {
/// Returns the item in the front of the queue, without checking if there are elements in the /// Returns the item in the front of the queue, without checking if there are elements in the
/// queue /// queue
/// ///
/// See [`Queue::dequeue_unchecked`] for safety /// # Safety
///
/// See [`Queue::dequeue_unchecked`]
#[inline] #[inline]
pub unsafe fn dequeue_unchecked(&mut self) -> T { pub unsafe fn dequeue_unchecked(&mut self) -> T {
self.rb.inner_dequeue_unchecked() self.rb.inner_dequeue_unchecked()
@ -526,6 +528,22 @@ impl<'a, T, const N: usize> Consumer<'a, T, N> {
self.rb.len() self.rb.len()
} }
/// Returns true if the queue is empty
///
/// # Examples
///
/// ```
/// use heapless::spsc::Queue;
///
/// let mut queue: Queue<u8, 235> = Queue::new();
/// let (mut producer, mut consumer) = queue.split();
/// assert!(consumer.is_empty());
/// ```
#[inline]
pub fn is_empty(&self) -> bool {
self.len() == 0
}
/// Returns the maximum number of elements the queue can hold /// Returns the maximum number of elements the queue can hold
#[inline] #[inline]
pub fn capacity(&self) -> usize { pub fn capacity(&self) -> usize {
@ -536,6 +554,7 @@ impl<'a, T, const N: usize> Consumer<'a, T, N> {
/// empty /// empty
/// ///
/// # Examples /// # Examples
///
/// ``` /// ```
/// use heapless::spsc::Queue; /// use heapless::spsc::Queue;
/// ///
@ -562,7 +581,9 @@ impl<'a, T, const N: usize> Producer<'a, T, N> {
/// Adds an `item` to the end of the queue, without checking if the queue is full /// Adds an `item` to the end of the queue, without checking if the queue is full
/// ///
/// See [`Queue::enqueue_unchecked`] for safety /// # Safety
///
/// See [`Queue::enqueue_unchecked`]
#[inline] #[inline]
pub unsafe fn enqueue_unchecked(&mut self, val: T) { pub unsafe fn enqueue_unchecked(&mut self, val: T) {
self.rb.inner_enqueue_unchecked(val) self.rb.inner_enqueue_unchecked(val)
@ -581,6 +602,22 @@ impl<'a, T, const N: usize> Producer<'a, T, N> {
self.rb.len() self.rb.len()
} }
/// Returns true if the queue is empty
///
/// # Examples
///
/// ```
/// use heapless::spsc::Queue;
///
/// let mut queue: Queue<u8, 235> = Queue::new();
/// let (mut producer, mut consumer) = queue.split();
/// assert!(producer.is_empty());
/// ```
#[inline]
pub fn is_empty(&self) -> bool {
self.len() == 0
}
/// Returns the maximum number of elements the queue can hold /// Returns the maximum number of elements the queue can hold
#[inline] #[inline]
pub fn capacity(&self) -> usize { pub fn capacity(&self) -> usize {
@ -894,14 +931,12 @@ mod tests {
let hash1 = { let hash1 = {
let mut hasher1 = hash32::FnvHasher::default(); let mut hasher1 = hash32::FnvHasher::default();
rb1.hash(&mut hasher1); rb1.hash(&mut hasher1);
let hash1 = hasher1.finish(); hasher1.finish()
hash1
}; };
let hash2 = { let hash2 = {
let mut hasher2 = hash32::FnvHasher::default(); let mut hasher2 = hash32::FnvHasher::default();
rb2.hash(&mut hasher2); rb2.hash(&mut hasher2);
let hash2 = hasher2.finish(); hasher2.finish()
hash2
}; };
assert_eq!(hash1, hash2); assert_eq!(hash1, hash2);
} }

View File

@ -209,6 +209,7 @@ impl<const N: usize> String<N> {
/// # Ok::<(), ()>(()) /// # Ok::<(), ()>(())
/// ``` /// ```
#[inline] #[inline]
#[allow(clippy::result_unit_err)]
pub fn push_str(&mut self, string: &str) -> Result<(), ()> { pub fn push_str(&mut self, string: &str) -> Result<(), ()> {
self.vec.extend_from_slice(string.as_bytes()) self.vec.extend_from_slice(string.as_bytes())
} }
@ -251,6 +252,7 @@ impl<const N: usize> String<N> {
/// # Ok::<(), ()>(()) /// # Ok::<(), ()>(())
/// ``` /// ```
#[inline] #[inline]
#[allow(clippy::result_unit_err)]
pub fn push(&mut self, c: char) -> Result<(), ()> { pub fn push(&mut self, c: char) -> Result<(), ()> {
match c.len_utf8() { match c.len_utf8() {
1 => self.vec.push(c as u8).map_err(|_| {}), 1 => self.vec.push(c as u8).map_err(|_| {}),
@ -315,7 +317,7 @@ impl<const N: usize> String<N> {
/// Ok::<(), ()>(()) /// Ok::<(), ()>(())
/// ``` /// ```
pub fn pop(&mut self) -> Option<char> { pub fn pop(&mut self) -> Option<char> {
let ch = self.chars().rev().next()?; let ch = self.chars().next_back()?;
// pop bytes that correspond to `ch` // pop bytes that correspond to `ch`
for _ in 0..ch.len_utf8() { for _ in 0..ch.len_utf8() {
@ -518,21 +520,13 @@ impl<const N1: usize, const N2: usize> PartialEq<String<N2>> for String<N1> {
fn eq(&self, rhs: &String<N2>) -> bool { fn eq(&self, rhs: &String<N2>) -> bool {
str::eq(&**self, &**rhs) str::eq(&**self, &**rhs)
} }
fn ne(&self, rhs: &String<N2>) -> bool {
str::ne(&**self, &**rhs)
}
} }
// String<N> == str // String<N> == str
impl<const N: usize> PartialEq<str> for String<N> { impl<const N: usize> PartialEq<str> for String<N> {
#[inline] #[inline]
fn eq(&self, other: &str) -> bool { fn eq(&self, other: &str) -> bool {
str::eq(&self[..], &other[..]) str::eq(self, other)
}
#[inline]
fn ne(&self, other: &str) -> bool {
str::ne(&self[..], &other[..])
} }
} }
@ -540,11 +534,7 @@ impl<const N: usize> PartialEq<str> for String<N> {
impl<const N: usize> PartialEq<&str> for String<N> { impl<const N: usize> PartialEq<&str> for String<N> {
#[inline] #[inline]
fn eq(&self, other: &&str) -> bool { fn eq(&self, other: &&str) -> bool {
str::eq(&self[..], &other[..]) str::eq(self, &other[..])
}
#[inline]
fn ne(&self, other: &&str) -> bool {
str::ne(&self[..], &other[..])
} }
} }
@ -552,11 +542,7 @@ impl<const N: usize> PartialEq<&str> for String<N> {
impl<const N: usize> PartialEq<String<N>> for str { impl<const N: usize> PartialEq<String<N>> for str {
#[inline] #[inline]
fn eq(&self, other: &String<N>) -> bool { fn eq(&self, other: &String<N>) -> bool {
str::eq(&self[..], &other[..]) str::eq(self, &other[..])
}
#[inline]
fn ne(&self, other: &String<N>) -> bool {
str::ne(&self[..], &other[..])
} }
} }
@ -564,11 +550,7 @@ impl<const N: usize> PartialEq<String<N>> for str {
impl<const N: usize> PartialEq<String<N>> for &str { impl<const N: usize> PartialEq<String<N>> for &str {
#[inline] #[inline]
fn eq(&self, other: &String<N>) -> bool { fn eq(&self, other: &String<N>) -> bool {
str::eq(&self[..], &other[..]) str::eq(self, &other[..])
}
#[inline]
fn ne(&self, other: &String<N>) -> bool {
str::ne(&self[..], &other[..])
} }
} }

View File

@ -76,6 +76,7 @@ impl<T, const N: usize> Vec<T, N> {
/// v.extend_from_slice(&[1, 2, 3]).unwrap(); /// v.extend_from_slice(&[1, 2, 3]).unwrap();
/// ``` /// ```
#[inline] #[inline]
#[allow(clippy::result_unit_err)]
pub fn from_slice(other: &[T]) -> Result<Self, ()> pub fn from_slice(other: &[T]) -> Result<Self, ()>
where where
T: Clone, T: Clone,
@ -210,6 +211,7 @@ impl<T, const N: usize> Vec<T, N> {
/// vec.extend_from_slice(&[2, 3, 4]).unwrap(); /// vec.extend_from_slice(&[2, 3, 4]).unwrap();
/// assert_eq!(*vec, [1, 2, 3, 4]); /// assert_eq!(*vec, [1, 2, 3, 4]);
/// ``` /// ```
#[allow(clippy::result_unit_err)]
pub fn extend_from_slice(&mut self, other: &[T]) -> Result<(), ()> pub fn extend_from_slice(&mut self, other: &[T]) -> Result<(), ()>
where where
T: Clone, T: Clone,
@ -257,7 +259,7 @@ impl<T, const N: usize> Vec<T, N> {
debug_assert!(!self.is_empty()); debug_assert!(!self.is_empty());
self.len -= 1; self.len -= 1;
(self.buffer.get_unchecked_mut(self.len).as_ptr() as *const T).read() self.buffer.get_unchecked_mut(self.len).as_ptr().read()
} }
/// Appends an `item` to the back of the collection /// Appends an `item` to the back of the collection
@ -305,6 +307,7 @@ impl<T, const N: usize> Vec<T, N> {
/// new_len is less than len, the Vec is simply truncated. /// new_len is less than len, the Vec is simply truncated.
/// ///
/// See also [`resize_default`](Self::resize_default). /// See also [`resize_default`](Self::resize_default).
#[allow(clippy::result_unit_err)]
pub fn resize(&mut self, new_len: usize, value: T) -> Result<(), ()> pub fn resize(&mut self, new_len: usize, value: T) -> Result<(), ()>
where where
T: Clone, T: Clone,
@ -331,6 +334,7 @@ impl<T, const N: usize> Vec<T, N> {
/// If `new_len` is less than `len`, the `Vec` is simply truncated. /// If `new_len` is less than `len`, the `Vec` is simply truncated.
/// ///
/// See also [`resize`](Self::resize). /// See also [`resize`](Self::resize).
#[allow(clippy::result_unit_err)]
pub fn resize_default(&mut self, new_len: usize) -> Result<(), ()> pub fn resize_default(&mut self, new_len: usize) -> Result<(), ()>
where where
T: Clone + Default, T: Clone + Default,
@ -934,9 +938,7 @@ impl<T, const N: usize> Iterator for IntoIter<T, N> {
type Item = T; type Item = T;
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
if self.next < self.vec.len() { if self.next < self.vec.len() {
let item = unsafe { let item = unsafe { self.vec.buffer.get_unchecked_mut(self.next).as_ptr().read() };
(self.vec.buffer.get_unchecked_mut(self.next).as_ptr() as *const T).read()
};
self.next += 1; self.next += 1;
Some(item) Some(item)
} else { } else {
@ -1001,7 +1003,7 @@ where
A: PartialEq<B>, A: PartialEq<B>,
{ {
fn eq(&self, other: &[B]) -> bool { fn eq(&self, other: &[B]) -> bool {
<[A]>::eq(self, &other[..]) <[A]>::eq(self, other)
} }
} }
@ -1011,7 +1013,7 @@ where
A: PartialEq<B>, A: PartialEq<B>,
{ {
fn eq(&self, other: &Vec<A, N>) -> bool { fn eq(&self, other: &Vec<A, N>) -> bool {
<[A]>::eq(other, &self[..]) <[A]>::eq(other, self)
} }
} }

View File

@ -88,7 +88,7 @@ fn contention() {
for i in 0..(2 * N) { for i in 0..(2 * N) {
sum = sum.wrapping_add(i as u32); sum = sum.wrapping_add(i as u32);
while let Err(_) = p.enqueue(i as u8) {} while p.enqueue(i as u8).is_err() {}
} }
println!("producer: {}", sum); println!("producer: {}", sum);
@ -137,7 +137,7 @@ fn mpmc_contention() {
for i in 0..(16 * N) { for i in 0..(16 * N) {
sum = sum.wrapping_add(i); sum = sum.wrapping_add(i);
println!("enqueue {}", i); println!("enqueue {}", i);
while let Err(_) = Q.enqueue(i) {} while Q.enqueue(i).is_err() {}
} }
s1.send(sum).unwrap(); s1.send(sum).unwrap();