What it is

This is a small Rust crate that provides a new control-flow primitive by means of a horrible macro.

RFC 243 (the ?/catch RFC) proposed a feature called "early exit from any block". It generalizes break to take an expression, as well as a lifetime, and to work inside all {} blocks, not just loops. break LIFE EXPR breaks out of the block/loop identified by the lifetime, and returns the given expression from the loop. Of course the expression must have the same type as the value that the block normally returns when it ends.

We can specify the desired feature by a source-to-source transformation (I doubt this is how it would be done if the feature were added to the language, but it does show that no new language features or control-flow primitives are truly required):

Input:

rust let x = 'a: { break 'a 0; // * 1 // ** };

Output (asterisks show corresponding lines):

```rust let x = { let ret; 'a: loop { ret = { ret = 0; // * break 'a; // *

        1         // **
    };
    break 'a;
}
ret

}; ```

Well, that was tedious to write (and read). Let's not do that again.

```rust

[macrouse] extern crate namedblock;

[macrouse] extern crate staticcond; // not needed on nightly

let x = block!('a: { break 'a 0; 1 }); ```

Fixed!

How to use it

First, add "named-block" as a dependency in Cargo.toml. Then, add #[macro_use] extern crate named_block; at the top of your crate root.

If you are on nightly Rust, you can enable the "nightly" Cargo feature and skip the second step. Otherwise, you need to add "static-cond" in Cargo.toml and #[macro_use] extern crate static_cond; as well. (Check this crate's Cargo.toml to see which version of "static-cond" to use.)

How it works

The block! macro uses (a lot of) recursion to walk through your code and perform the source-to-source translation described above. The ret variable is gensymmed using hygiene and cannot collide with other variable names or even nested calls to block!. Neat macro tricks include using a "parsing stack" to descend into token trees, and generating new macros on the fly to do comparisons. See the commented macro source for more details.

Limitations