Skip to content

array::map and array::try_map do not drop ZSTs properly #152211

@theemathas

Description

@theemathas

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)

Metadata

Metadata

Assignees

Labels

A-ZSTArea: Zero-sized types (ZSTs).A-arrayArea: `[T; N]`A-collectionsArea: `std::collections`A-destructorsArea: Destructors (`Drop`, …)A-panicArea: Panicking machineryC-bugCategory: This is a bug.T-libsRelevant to the library team, which will review and decide on the PR/issue.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions