Closed
Description
I tried this code:
// compile with opt-level=2 or higher
use std::collections::VecDeque;
#[derive(Clone)]
struct Droppy;
impl Drop for Droppy {
fn drop(&mut self) {
println!("dropped!");
}
}
fn main() {
let mut buf1 = VecDeque::from(vec![Droppy; usize::MAX]);
let mut buf2 = VecDeque::from(vec![Droppy]);
let total = buf1.len() as u128 + buf2.len() as u128;
println!("{} + {} = {}", buf1.len(), buf2.len(), total);
buf1.append(&mut buf2);
let total = buf1.len() as u128 + buf2.len() as u128;
println!("{} + {} = {}", buf1.len(), buf2.len(), total);
}
I expected to see this happen: A capacity overflow panic, followed by 264 lines of dropped!
.
Instead, this happened:
18446744073709551615 + 1 = 18446744073709551616
0 + 0 = 0
This is caused by VecDeque::append()
using a wrapping addition for the length when T::IS_ZST
:
pub fn append(&mut self, other: &mut Self) {
if T::IS_ZST {
self.len += other.len;
other.len = 0;
other.head = 0;
return;
}
/* ... */
}
Meta
rustc --version --verbose
:
rustc 1.69.0-nightly (c5c7d2b37 2023-02-24)
binary: rustc
commit-hash: c5c7d2b37780dac1092e75f12ab97dd56c30861d
commit-date: 2023-02-24
host: x86_64-unknown-linux-gnu
release: 1.69.0-nightly
LLVM version: 15.0.7