some docs, discovered Vec::unsize is unsound

This commit is contained in:
missing 2022-05-16 10:02:03 -05:00 committed by missing
parent 091ce53368
commit 9cd5a6b309
2 changed files with 29 additions and 3 deletions

View file

@ -31,9 +31,11 @@
//! Box::new(true) as _ //! Box::new(true) as _
//! ]; //! ];
//! let vec_unsized: Vec<dyn Debug> = vec![unsized: 1, "foo", true]; //! let vec_unsized: Vec<dyn Debug> = vec![unsized: 1, "foo", true];
//! # assert_eq!(format!("{:?}", vec), "[1, 2, 3]"); //! let vec_from_elem: Vec<i32> = vec![3; 5];
//! # assert_eq!(vec, [1, 2, 3]);
//! # assert_eq!(format!("{:?}", vec_boxed), r#"[1, "foo", true]"#); //! # assert_eq!(format!("{:?}", vec_boxed), r#"[1, "foo", true]"#);
//! # assert_eq!(format!("{:?}", vec_unsized), r#"[1, "foo", true]"#); //! # assert_eq!(format!("{:?}", vec_unsized), r#"[1, "foo", true]"#);
//! # assert_eq!(vec_from_elem, [3; 5]);
//! ``` //! ```
//! //!
//! A vector can be pushed to with [`Vec::push`]: //! A vector can be pushed to with [`Vec::push`]:
@ -63,6 +65,18 @@
//! # assert_eq!(format!("{:?}", vec), r#"[1, "foo", true, 2, "bar", false]"#); //! # assert_eq!(format!("{:?}", vec), r#"[1, "foo", true, 2, "bar", false]"#);
//! ``` //! ```
//! //!
//! Finally, a vector can be `unsize`d to another vector:
//!
//! ```should_panic
//! # use dyn_vec::prelude::{*, vec};
//! # use std::fmt::Debug;
//! let vec: Vec<i32> = vec![1, 2, 3];
//! // vec.push_unsize("foo"); // not yet...
//! let mut vec: Vec<dyn Debug> = vec.unsize();
//! vec.push_unsize("foo"); // now we can!
//! # assert_eq!(format!("{:?}", vec), r#"[1, 2, 3, "foo"]"#);
//! ```
//!
//! # Data Layout //! # Data Layout
//! //!
//! ```text //! ```text
@ -425,6 +439,10 @@ impl<T: ?Sized> Vec<T> {
/// Converts a `Vec<T: Sized>` into a `Vec<U: ?Sized>`, given that `T` can be `CoerceUnsized` into `U`. /// Converts a `Vec<T: Sized>` into a `Vec<U: ?Sized>`, given that `T` can be `CoerceUnsized` into `U`.
pub fn unsize<U: ?Sized>(self) -> Vec<U> where for<'a> &'a T: CoerceUnsized<&'a U> { pub fn unsize<U: ?Sized>(self) -> Vec<U> where for<'a> &'a T: CoerceUnsized<&'a U> {
#![allow(unreachable_code)]
// FIXME: when fixed, make the 2 relevant tests not should_panic (test::unsize and the line 70 doctest)
panic!("Vec::unsize is unsound rn, sorry yall");
let new_vec = Vec::<U> { let new_vec = Vec::<U> {
ptr: self.ptr, ptr: self.ptr,
len: self.len, len: self.len,
@ -543,7 +561,6 @@ impl<T: ?Sized> Drop for Vec<T> {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { unsafe {
for i in 0..self.len { for i in 0..self.len {
println!("dropping {}", i);
drop_in_place(self.get_unchecked_mut(i)); drop_in_place(self.get_unchecked_mut(i));
} }
self.dealloc(); self.dealloc();
@ -581,7 +598,7 @@ impl<T: ?Sized> IndexMut<usize> for Vec<T> {
/// ``` /// ```
/// # use dyn_vec::prelude::{vec, Vec}; /// # use dyn_vec::prelude::{vec, Vec};
/// # use std::fmt::Debug; /// # use std::fmt::Debug;
/// let vec1: Vec<dyn Debug> = vec![1, 2, 3].unsize(); /// let vec1: Vec<i32> = vec![1, 2, 3];
/// let vec2: Vec<dyn Debug> = vec![box: /// let vec2: Vec<dyn Debug> = vec![box:
/// Box::new(1) as _, /// Box::new(1) as _,
/// Box::new(String::from("foo")) as _, /// Box::new(String::from("foo")) as _,

View file

@ -187,4 +187,13 @@ fn with_capacity() {
// should have realloc'ed by now // should have realloc'ed by now
assert_ne!(prev_ptr, vec.as_ptr()); assert_ne!(prev_ptr, vec.as_ptr());
}
#[should_panic = "Vec::unsize is unsound rn, sorry yall"]
#[test]
fn unsize() {
let vec = vec![1, 2, 3];
let mut vec: Vec<dyn Debug> = vec.unsize();
vec.push_unsize(String::from("foo"));
assert_eq!(vec.debug(), "[1, 2, 3, \"foo\"]");
} }