From 0f30b7dd87b8555698ca7e7de360b037230e1f23 Mon Sep 17 00:00:00 2001 From: Justus K Date: Sun, 13 Dec 2020 10:02:36 +0100 Subject: [PATCH 1/3] fix panic if converting ZST Vec to VecDeque --- library/alloc/src/collections/vec_deque/mod.rs | 8 ++++++-- library/alloc/tests/vec_deque.rs | 7 +++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs index 57807bc545390..1303b58e31c98 100644 --- a/library/alloc/src/collections/vec_deque/mod.rs +++ b/library/alloc/src/collections/vec_deque/mod.rs @@ -2793,8 +2793,12 @@ impl From> for VecDeque { let len = other.len(); // We need to extend the buf if it's not a power of two, too small - // or doesn't have at least one free space - if !buf.capacity().is_power_of_two() + // or doesn't have at least one free space. + // We check if `T` is a ZST in the first condition, + // because `usize::MAX` (the capacity returned by `capacity()` for ZST) + // is not a power of zero and thus it'll always try + // to reserve more memory which will panic for ZST (rust-lang/rust#78532) + if (!buf.capacity().is_power_of_two() && mem::size_of::() != 0) || (buf.capacity() < (MINIMUM_CAPACITY + 1)) || (buf.capacity() == len) { diff --git a/library/alloc/tests/vec_deque.rs b/library/alloc/tests/vec_deque.rs index 705f0d62fbb7a..a962a5494a9a4 100644 --- a/library/alloc/tests/vec_deque.rs +++ b/library/alloc/tests/vec_deque.rs @@ -1728,3 +1728,10 @@ fn test_zero_sized_push() { } } } + +#[test] +fn test_from_zero_sized_vec() { + let v = vec![(); 100]; + let queue = VecDeque::from(v); + assert!(queue.len(), 100); +} From d75618e7a2517d4b39c4e50ff1644f595a86e92b Mon Sep 17 00:00:00 2001 From: Justus K Date: Sun, 13 Dec 2020 10:21:24 +0100 Subject: [PATCH 2/3] replace assert! with assert_eq! --- library/alloc/tests/vec_deque.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/alloc/tests/vec_deque.rs b/library/alloc/tests/vec_deque.rs index a962a5494a9a4..0919b1325bceb 100644 --- a/library/alloc/tests/vec_deque.rs +++ b/library/alloc/tests/vec_deque.rs @@ -1733,5 +1733,5 @@ fn test_zero_sized_push() { fn test_from_zero_sized_vec() { let v = vec![(); 100]; let queue = VecDeque::from(v); - assert!(queue.len(), 100); + assert_eq!(queue.len(), 100); } From 09d528ec155f77349001fa7eb6c3ae3363f41412 Mon Sep 17 00:00:00 2001 From: Justus K Date: Sun, 13 Dec 2020 15:18:38 +0100 Subject: [PATCH 3/3] fix typo --- library/alloc/src/collections/vec_deque/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs index 1303b58e31c98..9e54c15ea6a0b 100644 --- a/library/alloc/src/collections/vec_deque/mod.rs +++ b/library/alloc/src/collections/vec_deque/mod.rs @@ -2796,7 +2796,7 @@ impl From> for VecDeque { // or doesn't have at least one free space. // We check if `T` is a ZST in the first condition, // because `usize::MAX` (the capacity returned by `capacity()` for ZST) - // is not a power of zero and thus it'll always try + // is not a power of two and thus it'll always try // to reserve more memory which will panic for ZST (rust-lang/rust#78532) if (!buf.capacity().is_power_of_two() && mem::size_of::() != 0) || (buf.capacity() < (MINIMUM_CAPACITY + 1))