Conditions for `drop` to be called during unwinding

Hello,

struct PanicInDrop;
impl Drop for PanicInDrop {
    fn drop(&mut self) {
        panic!()
    }
}
struct PrintInDrop(String);
impl Drop for PrintInDrop {
    fn drop(&mut self) {
        print!("{}.", self.0);
    }
}

fn f(_arg: PanicInDrop) -> PrintInDrop {
    let output = PrintInDrop(String::from("2"));
    {
        PrintInDrop(String::from("3"));
    }
    output
}

fn main() {
    PrintInDrop(String::from("1"));
    f(PanicInDrop);
}

I ran the code above, and this was the content from the standard output:

1.3.

Why was 2. not printed?

Output of cargo --version:

cargo 1.91.1 (ea2d97820 2025-10-10)
1 Like

Unflushed stdout buffer?

Looks like this issue.

1 Like

I do not think that it is due to the state of the buffer. Here is a similar example, but I am using loop {} instead of printing:

struct PanicInDrop;
impl Drop for PanicInDrop {
    fn drop(&mut self) {
        panic!()
    }
}
struct LoopInDrop;
impl Drop for LoopInDrop {
    fn drop(&mut self) {
        loop {}
    }
}
fn f(_arg: PanicInDrop) -> LoopInDrop {
    LoopInDrop
}
fn main() {
    f(PanicInDrop);
}

I ran this, and it did terminate (rather than loop endlessly).

It does look like it has the same or a similar root cause.

Thank you very much for the help.