array::map and array::try_map do not drop ZST elements properly if the closure panics.
Additionally, array::try_map does not drop ZST elements properly if the closure "exits the loop" early.
In both cases, the elements that the closure didn't get to are never dropped at all.
Panicking in array::map
struct LoudDrop;
impl Drop for LoudDrop {
fn drop(&mut self) {
println!("drop");
}
}
// this prints "drop" only once instead of twice
fn main() {
let _ = [LoudDrop, LoudDrop].map(|_| panic!());
}
Panicking in array::try_map
#![feature(array_try_map)]
struct LoudDrop;
impl Drop for LoudDrop {
fn drop(&mut self) {
println!("drop");
}
}
// this prints "drop" only once instead of twice
fn main() {
let _ = [LoudDrop, LoudDrop].try_map(|_| panic!() as Result<(), ()>);
}
Early exit in array::try_map
#![feature(array_try_map)]
struct LoudDrop;
impl Drop for LoudDrop {
fn drop(&mut self) {
println!("drop");
}
}
// this prints "drop" only once instead of twice
fn main() {
let _ = [LoudDrop, LoudDrop].try_map(|_| Err::<(), ()>(()));
}
Relevant code:
|
impl<T: [const] Destruct, const N: usize, F> const Drop for Drain<'_, '_, T, N, F> { |
|
fn drop(&mut self) { |
|
if !T::IS_ZST { |
|
// SAFETY: we cant read more than N elements |
|
let slice = unsafe { |
|
from_raw_parts_mut::<[T]>( |
|
self.ptr.as_ptr(), |
|
// SAFETY: `start <= end` |
|
self.end.offset_from_unsigned(self.ptr.as_ptr()), |
|
) |
|
}; |
|
|
|
// SAFETY: By the type invariant, we're allowed to drop all these. (we own it, after all) |
|
unsafe { drop_in_place(slice) } |
|
} |
|
} |
|
} |
Meta
Reproducible on the playground with version 1.95.0-nightly (2026-02-05 f889772d6500faebcac5)
array::mapandarray::try_mapdo not drop ZST elements properly if the closure panics.Additionally,
array::try_mapdoes not drop ZST elements properly if the closure "exits the loop" early.In both cases, the elements that the closure didn't get to are never dropped at all.
Panicking in array::map
Panicking in array::try_map
Early exit in array::try_map
Relevant code:
rust/library/core/src/array/drain.rs
Lines 92 to 108 in a3ceeeb
Meta
Reproducible on the playground with version
1.95.0-nightly (2026-02-05 f889772d6500faebcac5)