1. "Protect/handle", a.k.a. "make it look like try/catch": this version
pursues the arrangement with protected-code coming first and handlers
coming second. To do this, the protected-code has to be suspended in a
closure, which is then passed to a temporary struct, which is
responsible for both capturing the remaining handler-part and firing the
push/run/pop cycle together at the end. Uses of it look like this:
let b = do OutOfKittens.protect {
do_some_stuff();
that_might_raise();
out_of_kittens();
};
do b.handle |t| {
UseAardvarksInstead
}
It's not really an ideal use of our 'do' syntax, nor are many other
variants of this API I've tried. It might read slightly better (or
worse) as such:
(do OutOfKittens.protect {
do_some_stuff();
that_might_raise();
out_of_kittens();
}).handle(|t|
UseAardvarksInstead
);
This is my preferred arrangement, though without the parens. The primary
reason is because I always prefer the exceptional flow to come last.
I could also imagine something like:
do protect {
...
}.handle::<OutOfKittens>(|ex|
).handle::<OutOfMilk>(|ex|
);
2. "Guard", a.k.a. "make it look like RAII": this version has only a
single "floating in space" handler-block that is assigned to a temporary
guard object in the current scope, and all subsequent code in that scope
is protected. Reads like this:
{
let _g = OutOfKittens.guard(|t| UseAardvarksInstead);
do_some_stuff();
that_might_raise();
out_of_kittens();
}
Downsides of this mechanism are that a user might try to move _g out of
the current frame or otherwise tamper with it -- we might need to do
some tricks with the region system to prevent that -- and it gives rise
to this somewhat artificial _g variable and otherwise unclear extra
block to contain it.
3. "Trap/in", a.k.a. "the system I like the look of best": this is the
version Patrick suggested yesterday. It sets up the handlers in the head
of a do-block and then invokes the protected code. It's order-inverted
from protect/handle -- the handlers come before the protected code --
but it still reads ok to my eyes, and seems to play nicely with our
existing syntax:
do OutOfKittens.trap(|t| UseAardvarksInstead).in {
do_some_stuff();
that_might_raise();
out_of_kittens();
}
_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev