Skip to content

Box sometimes forgets to drop its allocator when the Box is conditionally initialized. #131082

@theemathas

Description

@theemathas
Contributor

I tried this code:

#![feature(allocator_api)]

use std::alloc::{Allocator, AllocError, Layout, Global};
use std::ptr::NonNull;

struct LoudDropAllocator;

unsafe impl Allocator for LoudDropAllocator {
    fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
        Global.allocate(layout)
    }
    unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) {
        Global.deallocate(ptr, layout);
    }
}
impl Drop for LoudDropAllocator {
    fn drop(&mut self) {
        println!("dropping allocator...");
    }
}

struct HasDrop;
impl Drop for HasDrop {
    fn drop(&mut self) {}
}

fn foo() {
    println!("foo()");
    let b = Box::new_in(HasDrop, LoudDropAllocator);
    if true {
        drop(*b);
    } else {
        drop(b);
    }
}

fn bar() {
    println!("bar()");
    let b = Box::new_in(HasDrop, LoudDropAllocator);
    if true {
        drop(*b);
    } else {
        // drop(b);
    }
}

fn main() {
    foo();
    bar();
}

I expected the program to output:

foo()
dropping allocator...
bar()
dropping allocator...

Instead it output:

foo()
bar()
dropping allocator...

Seems like there's something wrong with the drop flags.

Making HasDrop not implement Drop causes the program to behave as expected.

Meta

Reproducible on the playground with version 1.83.0-nightly (2024-09-30 fb4aebddd18d258046dd)

Activity

added
needs-triageThis issue may need triage. Remove it if it has been sufficiently triaged.
on Oct 1, 2024
beepster4096

beepster4096 commented on Oct 1, 2024

@beepster4096
Contributor

@rustbot claim

changed the title [-]Box sometimes leaks its allocator when its contents are conditionally initialized.[/-] [+]Box sometimes forgets to drop its allocator when the Box is conditionally initialized.[/+] on Oct 1, 2024
added
T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
A-MIRArea: Mid-level IR (MIR) - https://blog.rust-lang.org/2016/04/19/MIR.html
and removed
needs-triageThis issue may need triage. Remove it if it has been sufficiently triaged.
on Oct 1, 2024
beepster4096

beepster4096 commented on Oct 1, 2024

@beepster4096
Contributor

Likely caused by #100036. Tried it out on godbolt, and it doesn't reproduce before 1.72. (with RUSTC_BOOTSTRAP=1)

added a commit that references this issue on Jan 7, 2025
7104e01
linked a pull request that will close this issue on Jul 9, 2025
added 2 commits that reference this issue on Jul 21, 2025
33800e5
20c4d33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

A-MIRArea: Mid-level IR (MIR) - https://blog.rust-lang.org/2016/04/19/MIR.htmlA-allocatorsArea: Custom and system allocatorsA-boxArea: Our favorite opsem complicationC-bugCategory: This is a bug.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

    Participants

    @Enselic@theemathas@beepster4096@workingjubilee@rustbot

    Issue actions

      Box sometimes forgets to drop its allocator when the Box is conditionally initialized. · Issue #131082 · rust-lang/rust