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.
#[allow(clippy::wildcard_imports)]
use super::*;
use std::fmt::Debug;
impl<T: ?Sized> Default for Vec<T> {
fn default() -> Self {
Self::new()
}
}
impl<T: ?Sized + Debug> Debug for Vec<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_list().entries(self.iter()).finish()

View file

@ -1,5 +1,6 @@
//! Iteration.
#[allow(clippy::wildcard_imports)]
use super::*;
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`].
#[allow(clippy::module_name_repetitions)]
pub struct IterMut<'a, T: ?Sized> {
base: BaseIter<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`].
#[allow(clippy::module_name_repetitions)]
pub struct IntoIter<T: ?Sized> {
ptr: NonNull<u8>,
capacity: usize,
@ -205,7 +208,7 @@ impl<T> FromIterator<T> for Vec<T> {
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
let mut vec = Vec::new();
for item in iter.into_iter() {
for item in iter {
vec.push(item);
}

View file

@ -95,6 +95,8 @@
#![feature(coerce_unsized)]
#![warn(missing_docs)]
#![warn(clippy::pedantic)]
#![allow(clippy::must_use_candidate)]
#[cfg(test)]
mod test;
@ -171,16 +173,31 @@ impl<T: ?Sized> Vec<T> {
}
}
/// Creates a new vector with the given capacity, measured in bytes.
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();
Self {
ptr,
len: 0,
capacity: cap,
end_ptr: ptr,
_phantom: PhantomData
/// Creates a new vector that holds `len` copies of `v`.
///
/// Only avaliable when `T: Sized`.
pub fn from_elem(v: T, len: usize) -> Self where T: Sized + Clone {
let mut vec = Self::with_capacity(len);
for _ in 0..len {
vec.push(v.clone());
}
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.
@ -287,7 +304,7 @@ impl<T: ?Sized> Vec<T> {
let size = size_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;
self.set_extra_from_ptr(i, ptr::from_raw_parts(ptr.cast(), meta));
ptr = ptr.wrapping_add(size);
@ -344,6 +361,8 @@ impl<T: ?Sized> Vec<T> {
/// Gets a reference to the element at the specified index.
///
/// # Safety
///
/// Immediate UB if the index is out-of-bounds.
pub unsafe fn get_unchecked(&self, index: usize) -> &T {
&*self.get_ptr(index)
@ -362,6 +381,8 @@ impl<T: ?Sized> Vec<T> {
/// Gets a mutable reference to the element at the specified index.
///
/// # Safety
///
/// Immediate UB if the index is out-of-bounds.
pub unsafe fn get_unchecked_mut(&mut self, index: usize) -> &mut T {
&mut *(self.get_ptr(index) as *mut _)
@ -372,6 +393,11 @@ impl<T: ?Sized> Vec<T> {
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.
pub fn capacity(&self) -> usize {
self.capacity
@ -448,13 +474,16 @@ impl<T> Vec<[T]> {
///
/// Only avaliable for `Vec<[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`
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 end = self.end_ptr.as_ptr() as usize;
debug_assert_eq!((end - start) % size_of::<T>(), 0);
(end - start) / size_of::<T>() // integer division!
})
}
@ -464,13 +493,16 @@ impl<T> Vec<[T]> {
///
/// Only avaliable for `Vec<[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`
unsafe {
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 end = self.end_ptr.as_ptr() as usize;
debug_assert_eq!((end - start) % size_of::<T>(), 0);
(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> {
fn drop(&mut self) {
unsafe {
@ -582,7 +605,7 @@ macro_rules! vec {
vec
}};
($elem:expr; $n:expr) => {
compile_error!("dyn_vec::vec![T; N] is currently not supported");
$crate::Vec::from_elem($elem, $n)
};
($($elem:expr),+ $(,)?) => {{
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];
assert_eq!(vec2.debug(), vec3.debug());
let vec4: Vec<i32> = vec![3; 5];
assert_eq!(vec4, [3; 5]);
}
#[test]
@ -177,4 +180,11 @@ fn with_capacity() {
vec.push(4);
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());
}