April 28, 2017
Writing `@nogc` code? Want to throw exceptions? Yeah, I know, painful. We can do this already:

void foo() @nogc {
    static const exception = new Exception("message can't change");
    if(<whatever>) throw exception; // no information about <whatever> is possible
}

But, we get limited information and no information at all that's available at runtime. We also have to have one of those exceptions for each error condition in the function. All in all, not ideal. So:


http://code.dlang.org/packages/nogc


And this compiles:

// text is @system because it returns a slice to a static array
// if you need to store the string you'll need to make a copy
// since consecutive calls will return the same slice and it will
// be mutated
@nogc @system unittest { // look ma, @nogc!
    import nogc.conv: text;
    // works with basic types and user defined structs/classes
    assert(text(1, " ", "foo", " ", 2.0) == "1 foo 2.000000");
}


// enforce is @safe, since it internally makes a call to `text` but
// immediately throws an exception, and casting it to `string` makes
// it immutable. Ugly but it works.
@nogc @safe unittest { // still @nogc!
    import nogc.exception: enforce;
    import nogc.conv: text;
    const expected = 1;
    const actual = 1;
    enforce(actual == expected, "Expected: ", expected, " but got: ", actual);
}


Notice that you don't call `text` after the condition in `enforce`. In practical use, I nearly always called `std.exception.enforce` with a second argument of `std.conv.text(...)`, so might as well make it easier here. Obviously `enforce(<whatever>, "...")` still works since it's a special case of passing in variadic arguments anyway.

Atila