From 6dac8c8491d3e56cc2097572809352c24bd67a1d Mon Sep 17 00:00:00 2001 From: Seph Gentle Date: Fri, 10 May 2024 15:39:53 +1000 Subject: [PATCH] Added failing test for servo#353 and fixed bug (#354) --- src/lib.rs | 3 ++- src/tests.rs | 20 ++++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 75c277f..da61d95 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -961,10 +961,11 @@ impl SmallVec { // SAFETY: see above debug_assert!(self.spilled()); let len = self.len(); - let (ptr, cap) = self.raw.heap; + let cap = self.raw.heap.1; if len == cap { self.reserve(1); } + let ptr = self.raw.heap.0; ptr.as_ptr().add(len).write(value); self.set_len(len + 1) } diff --git a/src/tests.rs b/src/tests.rs index 1b766c2..133d593 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -1128,3 +1128,23 @@ fn max_insert() { let mut sv: SmallVec = smallvec![0]; sv.insert(usize::MAX, 0); } + +#[test] +fn collect_from_iter() { + // Regression test for https://github.com/servo/rust-smallvec/issues/353 + struct IterNoHint(I); + + impl Iterator for IterNoHint { + type Item = I::Item; + fn next(&mut self) -> Option { self.0.next() } + + // no implementation of size_hint means it returns (0, None) - which forces from_iter to + // grow the allocated space iteratively. + } + + // A length of 3 is fine to trigger this bug under valgrind, but making the vector 1 million + // elements makes it crash - which is much easier to detect. + let iter = IterNoHint(std::iter::repeat(1u8).take(1_000_000)); + + let _y: SmallVec = SmallVec::from_iter(iter); +}