> Right now longjmp()ing over rust code is not a great idea for a couple reasons, but because leaks are currently always allowed in rust, it arguably follows the rules at least in some cases (doing so could cause problems, of course).
In the general case, skipping destructors of objects you don't own (through longjmp(), killing a single thread, etc.) has never been allowed in Rust: at any particular point in the program, you're only allowed to skip destructors of objects that you currently own, or can otherwise gain ownership of.
For instance, the thread::scope() API, after running the spawning thread's closure, uses a destructor* to join all the created threads. However, if a program could longjmp() past that destructor, then the spawning thread could access its variables again while the created threads are still using them, resulting in a data race. (This is the same issue that the original thread::scoped() API had.)
let mut x = 0;
let mut jmp_buf = JmpBuf::default();
if setjmp(&mut jmp_buf) == 0 {
std::thread::scope(|s| {
s.spawn(|| loop { x += 1; });
longjmp(&jmp_buf, 1);
});
} else {
loop { println!("{x}"); } /* the created thread is still changing the value of x! */
}
That is to say, longjmp() has always been a very unsafe operation, which can only be sound if you're in control of every single destructor which it skips. A Leak trait wouldn't change anything in that regard.
* Or rather, a catch_unwind() followed by a resume_unwind(), which is mostly equivalent to a destructor in this context.
In the general case, skipping destructors of objects you don't own (through longjmp(), killing a single thread, etc.) has never been allowed in Rust: at any particular point in the program, you're only allowed to skip destructors of objects that you currently own, or can otherwise gain ownership of.
For instance, the thread::scope() API, after running the spawning thread's closure, uses a destructor* to join all the created threads. However, if a program could longjmp() past that destructor, then the spawning thread could access its variables again while the created threads are still using them, resulting in a data race. (This is the same issue that the original thread::scoped() API had.)
That is to say, longjmp() has always been a very unsafe operation, which can only be sound if you're in control of every single destructor which it skips. A Leak trait wouldn't change anything in that regard.* Or rather, a catch_unwind() followed by a resume_unwind(), which is mostly equivalent to a destructor in this context.