-
-
Notifications
You must be signed in to change notification settings - Fork 14.6k
Open
Labels
A-ZSTArea: Zero-sized types (ZSTs).Area: Zero-sized types (ZSTs).A-arrayArea: `[T; N]`Area: `[T; N]`A-collectionsArea: `std::collections`Area: `std::collections`A-destructorsArea: Destructors (`Drop`, …)Area: Destructors (`Drop`, …)A-panicArea: Panicking machineryArea: Panicking machineryC-bugCategory: This is a bug.Category: This is a bug.T-libsRelevant to the library team, which will review and decide on the PR/issue.Relevant to the library team, which will review and decide on the PR/issue.
Description
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:
rust/library/core/src/array/drain.rs
Lines 92 to 108 in a3ceeeb
| 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)
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
A-ZSTArea: Zero-sized types (ZSTs).Area: Zero-sized types (ZSTs).A-arrayArea: `[T; N]`Area: `[T; N]`A-collectionsArea: `std::collections`Area: `std::collections`A-destructorsArea: Destructors (`Drop`, …)Area: Destructors (`Drop`, …)A-panicArea: Panicking machineryArea: Panicking machineryC-bugCategory: This is a bug.Category: This is a bug.T-libsRelevant to the library team, which will review and decide on the PR/issue.Relevant to the library team, which will review and decide on the PR/issue.