Closed

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.