Skip to content

sync::Once and panicking closure #31688

Closed
@ghost

Description

The documentation for sync::Once does not clarify what happens if given closure
panics. Currently I would rather expect that call_once will execute the closure
only once, whether it panics or not. But this is not what happens:

#![feature(recover)]

use std::sync::*;
use std::panic::recover;

static ONCE : Once = ONCE_INIT;

fn main() {
    for i in 1..10 {
        let _ = recover(|| { 
            ONCE.call_once(|| {
                let s = if i > 1 { "s" } else { ""};
                panic!("Once::call_once called {} time{}", i, s);
            }); 
        });
    }
}

Prints:

thread '<main>' panicked at 'Once::call_once called 1 time', <anon>:13
note: Run with `RUST_BACKTRACE=1` for a backtrace.
thread '<main>' panicked at 'Once::call_once called 2 times', <anon>:13
thread '<main>' panicked at 'Once::call_once called 3 times', <anon>:13
thread '<main>' panicked at 'Once::call_once called 4 times', <anon>:13
thread '<main>' panicked at 'Once::call_once called 5 times', <anon>:13
thread '<main>' panicked at 'Once::call_once called 6 times', <anon>:13
thread '<main>' panicked at 'Once::call_once called 7 times', <anon>:13
thread '<main>' panicked at 'Once::call_once called 8 times', <anon>:13
thread '<main>' panicked at 'Once::call_once called 9 times', <anon>:13

Either way documentation needs a slight improvement. And additionally code if
it is not a desired behaviour. As a side comment I will note that this
behaviour differs between languages. In C++ for example std::call_once to
proceed must not exit via exception, in Go on the other hand exiting via panic
counts as successful execution.

Metadata

Metadata

Assignees

No one assigned

    Labels

    T-libs-apiRelevant to the library API 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