vec![v; n] and clippy warnings

This commit is contained in:
missing 2022-05-16 09:42:00 -05:00 committed by missing
parent b24c62a662
commit 091ce53368
4 changed files with 68 additions and 24 deletions

View file

@ -1,9 +1,17 @@
//! Implements `Debug`, and `PartialEq` for various list-like types. //! Implements `Debug`, and `PartialEq` for various list-like types.
#[allow(clippy::wildcard_imports)]
use super::*; use super::*;
use std::fmt::Debug; use std::fmt::Debug;
impl<T: ?Sized> Default for Vec<T> {
fn default() -> Self {
Self::new()
}
}
impl<T: ?Sized + Debug> Debug for Vec<T> { impl<T: ?Sized + Debug> Debug for Vec<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_list().entries(self.iter()).finish() f.debug_list().entries(self.iter()).finish()

View file

@ -1,5 +1,6 @@
//! Iteration. //! Iteration.
#[allow(clippy::wildcard_imports)]
use super::*; use super::*;
struct BaseIter<T: ?Sized> { struct BaseIter<T: ?Sized> {
@ -93,6 +94,7 @@ impl<'a, T: ?Sized> IntoIterator for &'a mut Vec<T> {
} }
/// A by-mut iterator over the elements of a [`Vec`]. /// A by-mut iterator over the elements of a [`Vec`].
#[allow(clippy::module_name_repetitions)]
pub struct IterMut<'a, T: ?Sized> { pub struct IterMut<'a, T: ?Sized> {
base: BaseIter<T>, base: BaseIter<T>,
_phantom: PhantomData<&'a mut T> _phantom: PhantomData<&'a mut T>
@ -132,6 +134,7 @@ impl<T: ?Sized> IntoIterator for Vec<T> {
} }
/// A by-value iterator over the elements of a [`Vec`]. /// A by-value iterator over the elements of a [`Vec`].
#[allow(clippy::module_name_repetitions)]
pub struct IntoIter<T: ?Sized> { pub struct IntoIter<T: ?Sized> {
ptr: NonNull<u8>, ptr: NonNull<u8>,
capacity: usize, capacity: usize,
@ -205,7 +208,7 @@ impl<T> FromIterator<T> for Vec<T> {
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self { fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
let mut vec = Vec::new(); let mut vec = Vec::new();
for item in iter.into_iter() { for item in iter {
vec.push(item); vec.push(item);
} }

View file

@ -95,6 +95,8 @@
#![feature(coerce_unsized)] #![feature(coerce_unsized)]
#![warn(missing_docs)] #![warn(missing_docs)]
#![warn(clippy::pedantic)]
#![allow(clippy::must_use_candidate)]
#[cfg(test)] #[cfg(test)]
mod test; mod test;
@ -171,16 +173,31 @@ impl<T: ?Sized> Vec<T> {
} }
} }
/// Creates a new vector with the given capacity, measured in bytes. /// Creates a new vector that holds `len` copies of `v`.
pub fn with_capacity_bytes(cap: usize) -> Self { ///
let ptr = NonNull::new(unsafe { alloc(Layout::from_size_align(cap, 8).unwrap().pad_to_align()) }).unwrap(); /// Only avaliable when `T: Sized`.
Self { pub fn from_elem(v: T, len: usize) -> Self where T: Sized + Clone {
ptr, let mut vec = Self::with_capacity(len);
len: 0,
capacity: cap, for _ in 0..len {
end_ptr: ptr, vec.push(v.clone());
_phantom: PhantomData
} }
vec
}
/// Creates a new vector that can hold the given amount of `T`s.
///
/// Only avaliable when `T: Sized`.
pub fn with_capacity(cap: usize) -> Self where T: Sized {
Self::with_capacity_for::<T>(cap)
}
/// Creates a new vector with the given capacity, measured in bytes.\
pub fn with_capacity_bytes(cap: usize) -> Self {
let mut vec = Self::new();
unsafe { vec.realloc(cap); }
vec
} }
/// Creates a new vector with enough capacity to hold the given amount of `U`s. /// Creates a new vector with enough capacity to hold the given amount of `U`s.
@ -287,7 +304,7 @@ impl<T: ?Sized> Vec<T> {
let size = size_of_val(v); let size = size_of_val(v);
ptr = align_up_mut(ptr, align_of_val(v)); ptr = align_up_mut(ptr, align_of_val(v));
memcpy(v as *const _ as _, ptr, size); memcpy((v as *const T).cast(), ptr, size);
let meta = self.get_ptr(i).to_raw_parts().1; let meta = self.get_ptr(i).to_raw_parts().1;
self.set_extra_from_ptr(i, ptr::from_raw_parts(ptr.cast(), meta)); self.set_extra_from_ptr(i, ptr::from_raw_parts(ptr.cast(), meta));
ptr = ptr.wrapping_add(size); ptr = ptr.wrapping_add(size);
@ -344,6 +361,8 @@ impl<T: ?Sized> Vec<T> {
/// Gets a reference to the element at the specified index. /// Gets a reference to the element at the specified index.
/// ///
/// # Safety
///
/// Immediate UB if the index is out-of-bounds. /// Immediate UB if the index is out-of-bounds.
pub unsafe fn get_unchecked(&self, index: usize) -> &T { pub unsafe fn get_unchecked(&self, index: usize) -> &T {
&*self.get_ptr(index) &*self.get_ptr(index)
@ -362,6 +381,8 @@ impl<T: ?Sized> Vec<T> {
/// Gets a mutable reference to the element at the specified index. /// Gets a mutable reference to the element at the specified index.
/// ///
/// # Safety
///
/// Immediate UB if the index is out-of-bounds. /// Immediate UB if the index is out-of-bounds.
pub unsafe fn get_unchecked_mut(&mut self, index: usize) -> &mut T { pub unsafe fn get_unchecked_mut(&mut self, index: usize) -> &mut T {
&mut *(self.get_ptr(index) as *mut _) &mut *(self.get_ptr(index) as *mut _)
@ -372,6 +393,11 @@ impl<T: ?Sized> Vec<T> {
self.len self.len
} }
/// Returns `true` if the vector holds no elements.
pub fn is_empty(&self) -> bool {
self.len == 0
}
/// Returns the capacity, which is the size of the allocation in bytes. /// Returns the capacity, which is the size of the allocation in bytes.
pub fn capacity(&self) -> usize { pub fn capacity(&self) -> usize {
self.capacity self.capacity
@ -448,13 +474,16 @@ impl<T> Vec<[T]> {
/// ///
/// Only avaliable for `Vec<[T]>`. /// Only avaliable for `Vec<[T]>`.
pub fn as_slice_flatten(&self) -> &[T] { pub fn as_slice_flatten(&self) -> &[T] {
assert!(self.len > 0); if self.len == 0 {
return unsafe { slice::from_raw_parts(NonNull::dangling().as_ptr(), 0) }
}
// SAFETY: the slices should be contiguous by the logic of `push_raw_unchecked` // SAFETY: the slices should be contiguous by the logic of `push_raw_unchecked`
unsafe { unsafe {
slice::from_raw_parts(self.get_ptr(0).to_raw_parts().0 as _, { slice::from_raw_parts(self.get_ptr(0).to_raw_parts().0.cast(), {
let start = self.get_ptr(0).to_raw_parts().0 as usize; let start = self.get_ptr(0).to_raw_parts().0 as usize;
let end = self.end_ptr.as_ptr() as usize; let end = self.end_ptr.as_ptr() as usize;
debug_assert_eq!((end - start) % size_of::<T>(), 0);
(end - start) / size_of::<T>() // integer division! (end - start) / size_of::<T>() // integer division!
}) })
} }
@ -464,13 +493,16 @@ impl<T> Vec<[T]> {
/// ///
/// Only avaliable for `Vec<[T]>`. /// Only avaliable for `Vec<[T]>`.
pub fn as_mut_slice_flatten(&mut self) -> &mut [T] { pub fn as_mut_slice_flatten(&mut self) -> &mut [T] {
assert!(self.len > 0); if self.len == 0 {
return unsafe { slice::from_raw_parts_mut(NonNull::dangling().as_ptr(), 0) }
}
// SAFETY: the slices should be contiguous by the logic of `push_raw_unchecked` // SAFETY: the slices should be contiguous by the logic of `push_raw_unchecked`
unsafe { unsafe {
slice::from_raw_parts_mut(self.get_ptr(0).to_raw_parts().0 as _, { slice::from_raw_parts_mut(self.get_ptr(0).to_raw_parts().0 as _, {
let start = self.get_ptr(0).to_raw_parts().0 as usize; let start = self.get_ptr(0).to_raw_parts().0 as usize;
let end = self.end_ptr.as_ptr() as usize; let end = self.end_ptr.as_ptr() as usize;
debug_assert_eq!((end - start) % size_of::<T>(), 0);
(end - start) / size_of::<T>() // integer division! (end - start) / size_of::<T>() // integer division!
}) })
} }
@ -507,15 +539,6 @@ impl Vec<dyn Any> {
} }
} }
impl<T> Vec<T> {
/// Creates a new vector that can hold the given amount of `T`s.
///
/// Only avaliable when `T: Sized`.
pub fn with_capacity(cap: usize) -> Self {
Self::with_capacity_for::<T>(cap)
}
}
impl<T: ?Sized> Drop for Vec<T> { impl<T: ?Sized> Drop for Vec<T> {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { unsafe {
@ -582,7 +605,7 @@ macro_rules! vec {
vec vec
}}; }};
($elem:expr; $n:expr) => { ($elem:expr; $n:expr) => {
compile_error!("dyn_vec::vec![T; N] is currently not supported"); $crate::Vec::from_elem($elem, $n)
}; };
($($elem:expr),+ $(,)?) => {{ ($($elem:expr),+ $(,)?) => {{
let mut vec = $crate::Vec::new(); let mut vec = $crate::Vec::new();

View file

@ -50,6 +50,9 @@ fn all_macro() {
]; ];
let vec3: Vec<dyn Debug> = vec![unsized: 1, String::from("foo"), true]; let vec3: Vec<dyn Debug> = vec![unsized: 1, String::from("foo"), true];
assert_eq!(vec2.debug(), vec3.debug()); assert_eq!(vec2.debug(), vec3.debug());
let vec4: Vec<i32> = vec![3; 5];
assert_eq!(vec4, [3; 5]);
} }
#[test] #[test]
@ -177,4 +180,11 @@ fn with_capacity() {
vec.push(4); vec.push(4);
assert_eq!(prev_ptr, vec.as_ptr()); assert_eq!(prev_ptr, vec.as_ptr());
vec.push(5);
vec.push(6);
vec.push(7);
// should have realloc'ed by now
assert_ne!(prev_ptr, vec.as_ptr());
} }