/**
    The exception module defines all system-level exceptions and provides a
    mechanism to alter system-level error handling.

    Copyright: Copyright Sean Kelly 2005 - 2013.
    License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
    Authors:   Sean Kelly and $(HTTP jmdavisprog.com, Jonathan M Davis)
    Source:    $(DRUNTIMESRC core/_exception.d)
 */
module core.exception;

// Compiler lowers final switch default case to this (which is a runtime error)
void __switch_errorT()(string file = __FILE__, size_t line = __LINE__) @trusted
{
    // Consider making this a compile time check.
    version (D_Exceptions)
        throw staticError!SwitchError(file, line, null);
    else
        assert(0, "No appropriate switch clause found");
}

/**
 * Thrown on a range error.
 */
class RangeError : Error
{
    this( string file = __FILE__, size_t line = __LINE__, Throwable next = null ) @nogc nothrow pure @safe
    {
        super( "Range violation", file, line, next );
    }

    protected this( string msg, string file, size_t line, Throwable next = null ) @nogc nothrow pure @safe
    {
        super( msg, file, line, next );
    }
}

unittest
{
    {
        auto re = new RangeError();
        assert(re.file == __FILE__);
        assert(re.line == __LINE__ - 2);
        assert(re.next is null);
        assert(re.msg == "Range violation");
    }

    {
        auto re = new RangeError("hello", 42, new Exception("It's an Exception!"));
        assert(re.file == "hello");
        assert(re.line == 42);
        assert(re.next !is null);
        assert(re.msg == "Range violation");
    }
}

/**
 * Thrown when an out of bounds array index is accessed.
 */
class ArrayIndexError : RangeError
{
    /// Index into array
    const size_t index;
    /// Length of indexed array
    const size_t length;

    // Buffer to avoid GC allocations
    private immutable char[100] msgBuf = '\0';

    this(size_t index, size_t length, string file = __FILE__,
         size_t line = __LINE__, Throwable next = null) @nogc nothrow pure @safe
    {
        this.index  = index;
        this.length = length;

        // Constructing the message is a bit clumsy:
        // It's essentially `printf("index [%zu] is out of bounds for array of length [%zu]", index, length)`,
        // but even `snprintf` isn't `pure`.
        // Also string concatenation isn't `@nogc`, and casting to/from immutable isn't `@safe`
        import core.internal.string : unsignedToTempString;
        char[msgBuf.length] buf = void;
        char[20] tmpBuf = void;
        char[] sink = buf[];
        sink.rangeMsgPut("index [");
        sink.rangeMsgPut(unsignedToTempString!10(index, tmpBuf));
        sink.rangeMsgPut("] is out of bounds for array of length ");
        sink.rangeMsgPut(unsignedToTempString!10(length, tmpBuf));
        this.msgBuf = buf;
        super(msgBuf[0..$-sink.length], file, line, next);
    }
}

@safe pure unittest
{
    assert(new ArrayIndexError(900, 700).msg == "index [900] is out of bounds for array of length 700");
    // Ensure msg buffer doesn't overflow on large numbers
    assert(new ArrayIndexError(size_t.max, size_t.max-1).msg);
}

unittest
{
    try
    {
        _d_arraybounds_indexp("test", 400, 9, 3);
        assert(0, "no ArrayIndexError thrown");
    }
    catch (ArrayIndexError re)
    {
        assert(re.file   == "test");
        assert(re.line   == 400);
        assert(re.index  == 9);
        assert(re.length == 3);
    }
}

/**
 * Thrown when an out of bounds array slice is created
 */
class ArraySliceError : RangeError
{
    /// Lower/upper bound passed to slice: `array[lower .. upper]`
    const size_t lower, upper;
    /// Length of sliced array
    const size_t length;

    private immutable char[120] msgBuf = '\0';

    this(size_t lower, size_t upper, size_t length, string file = __FILE__,
         size_t line = __LINE__, Throwable next = null) @nogc nothrow pure @safe
    {
        this.lower  = lower;
        this.upper  = upper;
        this.length = length;

        // Constructing the message is a bit clumsy for the same reasons as ArrayIndexError
        import core.internal.string : unsignedToTempString;
        char[msgBuf.length] buf = void;
        char[20] tmpBuf = void;
        char[] sink = buf;
        sink.rangeMsgPut("slice [");
        sink.rangeMsgPut(unsignedToTempString!10(lower, tmpBuf));
        sink.rangeMsgPut(" .. ");
        sink.rangeMsgPut(unsignedToTempString!10(upper, tmpBuf));
        sink.rangeMsgPut("] ");
        if (lower > upper)
        {
            sink.rangeMsgPut("has a larger lower index than upper index");
        }
        else
        {
            sink.rangeMsgPut("extends past source array of length ");
            sink.rangeMsgPut(unsignedToTempString!10(length, tmpBuf));
        }

        this.msgBuf = buf;
        super(msgBuf[0..$-sink.length], file, line, next);
    }
}

@safe pure unittest
{
    assert(new ArraySliceError(40, 80, 20).msg == "slice [40 .. 80] extends past source array of length 20");
    assert(new ArraySliceError(90, 70, 20).msg == "slice [90 .. 70] has a larger lower index than upper index");
    // Ensure msg buffer doesn't overflow on large numbers
    assert(new ArraySliceError(size_t.max, size_t.max, size_t.max-1).msg);
}

unittest
{
    try
    {
        _d_arraybounds_slicep("test", 400, 1, 7, 3);
        assert(0, "no ArraySliceError thrown");
    }
    catch (ArraySliceError re)
    {
        assert(re.file   == "test");
        assert(re.line   == 400);
        assert(re.lower  == 1);
        assert(re.upper  == 7);
        assert(re.length == 3);
    }
}

/// Mini `std.range.primitives: put` for constructor of ArraySliceError / ArrayIndexError
private void rangeMsgPut(ref char[] r, scope const(char)[] e) @nogc nothrow pure @safe
{
    assert(r.length >= e.length); // don't throw ArraySliceError inside ArrayIndexError ctor
    r[0 .. e.length] = e[];
    r = r[e.length .. $];
}

/**
 * Thrown on an assert error.
 */
class AssertError : Error
{
    @safe pure nothrow @nogc this( string file, size_t line )
    {
        this(cast(Throwable)null, file, line);
    }

    @safe pure nothrow @nogc this( Throwable next, string file = __FILE__, size_t line = __LINE__ )
    {
        this( "Assertion failure", file, line, next);
    }

    @safe pure nothrow @nogc this( string msg, string file = __FILE__, size_t line = __LINE__, Throwable next = null )
    {
        super( msg, file, line, next );
    }
}

unittest
{
    {
        auto ae = new AssertError("hello", 42);
        assert(ae.file == "hello");
        assert(ae.line == 42);
        assert(ae.next is null);
        assert(ae.msg == "Assertion failure");
    }

    {
        auto ae = new AssertError(new Exception("It's an Exception!"));
        assert(ae.file == __FILE__);
        assert(ae.line == __LINE__ - 2);
        assert(ae.next !is null);
        assert(ae.msg == "Assertion failure");
    }

    {
        auto ae = new AssertError(new Exception("It's an Exception!"), "hello", 42);
        assert(ae.file == "hello");
        assert(ae.line == 42);
        assert(ae.next !is null);
        assert(ae.msg == "Assertion failure");
    }

    {
        auto ae = new AssertError("msg");
        assert(ae.file == __FILE__);
        assert(ae.line == __LINE__ - 2);
        assert(ae.next is null);
        assert(ae.msg == "msg");
    }

    {
        auto ae = new AssertError("msg", "hello", 42);
        assert(ae.file == "hello");
        assert(ae.line == 42);
        assert(ae.next is null);
        assert(ae.msg == "msg");
    }

    {
        auto ae = new AssertError("msg", "hello", 42, new Exception("It's an Exception!"));
        assert(ae.file == "hello");
        assert(ae.line == 42);
        assert(ae.next !is null);
        assert(ae.msg == "msg");
    }
}


/**
 * Thrown on finalize error.
 */
class FinalizeError : Error
{
    TypeInfo   info;

    this( TypeInfo ci, Throwable next, string file = __FILE__, size_t line = __LINE__ ) @safe pure nothrow @nogc
    {
        this(ci, file, line, next);
    }

    this( TypeInfo ci, string file = __FILE__, size_t line = __LINE__, Throwable next = null ) @safe pure nothrow @nogc
    {
        super( "Finalization error", file, line, next );
        super.info = SuppressTraceInfo.instance;
        info = ci;
    }

    override string toString() const @safe
    {
        return "An exception was thrown while finalizing an instance of " ~ info.toString();
    }
}

unittest
{
    ClassInfo info = new ClassInfo;
    info.name = "testInfo";

    {
        auto fe = new FinalizeError(info);
        assert(fe.file == __FILE__);
        assert(fe.line == __LINE__ - 2);
        assert(fe.next is null);
        assert(fe.msg == "Finalization error");
        assert(fe.info == info);
    }

    {
        auto fe = new FinalizeError(info, new Exception("It's an Exception!"));
        assert(fe.file == __FILE__);
        assert(fe.line == __LINE__ - 2);
        assert(fe.next !is null);
        assert(fe.msg == "Finalization error");
        assert(fe.info == info);
    }

    {
        auto fe = new FinalizeError(info, "hello", 42);
        assert(fe.file == "hello");
        assert(fe.line == 42);
        assert(fe.next is null);
        assert(fe.msg == "Finalization error");
        assert(fe.info == info);
    }

    {
        auto fe = new FinalizeError(info, "hello", 42, new Exception("It's an Exception!"));
        assert(fe.file == "hello");
        assert(fe.line == 42);
        assert(fe.next !is null);
        assert(fe.msg == "Finalization error");
        assert(fe.info == info);
    }
}

/**
 * Thrown on an out of memory error.
 */
class OutOfMemoryError : Error
{
    this(string file = __FILE__, size_t line = __LINE__, Throwable next = null ) @safe pure nothrow @nogc
    {
        this(true, file, line, next);
    }

    this(bool trace, string file = __FILE__, size_t line = __LINE__, Throwable next = null ) @safe pure nothrow @nogc
    {
        super("Memory allocation failed", file, line, next);
        if (!trace)
            this.info = SuppressTraceInfo.instance;
    }

    override string toString() const @trusted
    {
        return msg.length ? (cast()this).superToString() : "Memory allocation failed";
    }

    // kludge to call non-const super.toString
    private string superToString() @trusted
    {
        return super.toString();
    }
}

unittest
{
    {
        auto oome = new OutOfMemoryError();
        assert(oome.file == __FILE__);
        assert(oome.line == __LINE__ - 2);
        assert(oome.next is null);
        assert(oome.msg == "Memory allocation failed");
        assert(oome.toString.length);
    }

    {
        auto oome = new OutOfMemoryError("hello", 42, new Exception("It's an Exception!"));
        assert(oome.file == "hello");
        assert(oome.line == 42);
        assert(oome.next !is null);
        assert(oome.msg == "Memory allocation failed");
    }
}


/**
 * Thrown on an invalid memory operation.
 *
 * An invalid memory operation error occurs in circumstances when the garbage
 * collector has detected an operation it cannot reliably handle. The default
 * D GC is not re-entrant, so this can happen due to allocations done from
 * within finalizers called during a garbage collection cycle.
 */
class InvalidMemoryOperationError : Error
{
    this(string file = __FILE__, size_t line = __LINE__, Throwable next = null ) @safe pure nothrow @nogc
    {
        super( "Invalid memory operation", file, line, next );
        this.info = SuppressTraceInfo.instance;
    }

    override string toString() const @trusted
    {
        return msg.length ? (cast()this).superToString() : "Invalid memory operation";
    }

    // kludge to call non-const super.toString
    private string superToString() @trusted
    {
        return super.toString();
    }
}

unittest
{
    {
        auto oome = new InvalidMemoryOperationError();
        assert(oome.file == __FILE__);
        assert(oome.line == __LINE__ - 2);
        assert(oome.next is null);
        assert(oome.msg == "Invalid memory operation");
        assert(oome.toString.length);
    }

    {
        auto oome = new InvalidMemoryOperationError("hello", 42, new Exception("It's an Exception!"));
        assert(oome.file == "hello");
        assert(oome.line == 42);
        assert(oome.next !is null);
        assert(oome.msg == "Invalid memory operation");
    }
}


/**
* Thrown on a configuration error.
*/
class ForkError : Error
{
    this( string file = __FILE__, size_t line = __LINE__, Throwable next = null ) @nogc nothrow pure @safe
    {
        super( "fork() failed", file, line, next );
    }
}


/**
 * Thrown on a switch error.
 */
class SwitchError : Error
{
    @safe pure nothrow @nogc this( string file = __FILE__, size_t line = __LINE__, Throwable next = null )
    {
        super( "No appropriate switch clause found", file, line, next );
    }
}

unittest
{
    {
        auto se = new SwitchError();
        assert(se.file == __FILE__);
        assert(se.line == __LINE__ - 2);
        assert(se.next is null);
        assert(se.msg == "No appropriate switch clause found");
    }

    {
        auto se = new SwitchError("hello", 42, new Exception("It's an Exception!"));
        assert(se.file == "hello");
        assert(se.line == 42);
        assert(se.next !is null);
        assert(se.msg == "No appropriate switch clause found");
    }
}


/**
 * Thrown on a unicode conversion error.
 */
class UnicodeException : Exception
{
    size_t idx;

    this( string msg, size_t idx, string file = __FILE__, size_t line = __LINE__, Throwable next = null ) @safe pure nothrow @nogc
    {
        super( msg, file, line, next );
        this.idx = idx;
    }
}

unittest
{
    {
        auto ue = new UnicodeException("msg", 2);
        assert(ue.file == __FILE__);
        assert(ue.line == __LINE__ - 2);
        assert(ue.next is null);
        assert(ue.msg == "msg");
        assert(ue.idx == 2);
    }

    {
        auto ue = new UnicodeException("msg", 2, "hello", 42, new Exception("It's an Exception!"));
        assert(ue.file == "hello");
        assert(ue.line == 42);
        assert(ue.next !is null);
        assert(ue.msg == "msg");
        assert(ue.idx == 2);
    }
}


///////////////////////////////////////////////////////////////////////////////
// Overrides
///////////////////////////////////////////////////////////////////////////////


// NOTE: One assert handler is used for all threads.  Thread-local
//       behavior should occur within the handler itself.  This delegate
//       is __gshared for now based on the assumption that it will only
//       set by the main thread during program initialization.
private __gshared AssertHandler _assertHandler = null;


/**
Gets/sets assert hander. null means the default handler is used.
*/
alias AssertHandler = void function(string file, size_t line, string msg) nothrow;

/// ditto
@property AssertHandler assertHandler() @trusted nothrow @nogc
{
    return _assertHandler;
}

/// ditto
@property void assertHandler(AssertHandler handler) @trusted nothrow @nogc
{
    _assertHandler = handler;
}


///////////////////////////////////////////////////////////////////////////////
// Overridable Callbacks
///////////////////////////////////////////////////////////////////////////////


/**
 * A callback for assert errors in D.  The user-supplied assert handler will
 * be called if one has been supplied, otherwise an $(LREF AssertError) will be
 * thrown.
 *
 * Params:
 *  file = The name of the file that signaled this error.
 *  line = The line number on which this error occurred.
 */
extern (C) void onAssertError( string file = __FILE__, size_t line = __LINE__ ) nothrow
{
    if ( _assertHandler is null )
        throw staticError!AssertError(file, line);
    _assertHandler( file, line, null);
}


/**
 * A callback for assert errors in D.  The user-supplied assert handler will
 * be called if one has been supplied, otherwise an $(LREF AssertError) will be
 * thrown.
 *
 * Params:
 *  file = The name of the file that signaled this error.
 *  line = The line number on which this error occurred.
 *  msg  = An error message supplied by the user.
 */
extern (C) void onAssertErrorMsg( string file, size_t line, string msg ) nothrow
{
    if ( _assertHandler is null )
        throw staticError!AssertError(msg, file, line);
    _assertHandler( file, line, msg );
}


/**
 * A callback for unittest errors in D.  The user-supplied unittest handler
 * will be called if one has been supplied, otherwise the error will be
 * written to stderr.
 *
 * Params:
 *  file = The name of the file that signaled this error.
 *  line = The line number on which this error occurred.
 *  msg  = An error message supplied by the user.
 */
extern (C) void onUnittestErrorMsg( string file, size_t line, string msg ) nothrow
{
    onAssertErrorMsg( file, line, msg );
}


///////////////////////////////////////////////////////////////////////////////
// Internal Error Callbacks
///////////////////////////////////////////////////////////////////////////////

/**
 * A callback for general array bounds errors in D. A $(LREF RangeError) will be thrown.
 *
 * Params:
 *  file = The name of the file that signaled this error.
 *  line = The line number on which this error occurred.
 *
 * Throws:
 *  $(LREF RangeError).
 */
extern (C) void onRangeError( string file = __FILE__, size_t line = __LINE__ ) @trusted pure nothrow @nogc
{
    throw staticError!RangeError(file, line, null);
}

/**
 * A callback for array slice out of bounds errors in D.
 *
 * Params:
 *  lower  = the lower bound of the index passed of a slice
 *  upper  = the upper bound of the index passed of a slice or the index if not a slice
 *  length = length of the array
 *  file = The name of the file that signaled this error.
 *  line = The line number on which this error occurred.
 *
 * Throws:
 *  $(LREF ArraySliceError).
 */
extern (C) void onArraySliceError( size_t lower = 0, size_t upper = 0, size_t length = 0,
                              string file = __FILE__, size_t line = __LINE__ ) @trusted pure nothrow @nogc
{
    throw staticError!ArraySliceError(lower, upper, length, file, line, null);
}

/**
 * A callback for array index out of bounds errors in D.
 *
 * Params:
 *  index  = index in the array
 *  length = length of the array
 *  file = The name of the file that signaled this error.
 *  line = The line number on which this error occurred.
 *
 * Throws:
 *  $(LREF ArrayIndexError).
 */
extern (C) void onArrayIndexError( size_t index = 0, size_t length = 0,
                              string file = __FILE__, size_t line = __LINE__ ) @trusted pure nothrow @nogc
{
    throw staticError!ArrayIndexError(index, length, file, line, null);
}

/**
 * A callback for finalize errors in D.  A $(LREF FinalizeError) will be thrown.
 *
 * Params:
 *  info = The TypeInfo instance for the object that failed finalization.
 *  e = The exception thrown during finalization.
 *  file = The name of the file that signaled this error.
 *  line = The line number on which this error occurred.
 *
 * Throws:
 *  $(LREF FinalizeError).
 */
extern (C) void onFinalizeError( TypeInfo info, Throwable e, string file = __FILE__, size_t line = __LINE__ ) @trusted nothrow
{
    // This error is thrown during a garbage collection, so no allocation must occur while
    //  generating this object. So we use a preallocated instance
    throw staticError!FinalizeError(info, e, file, line);
}

version (D_BetterC)
{
    // When compiling with -betterC we use template functions so if they are
    // used the bodies are copied into the user's program so there is no need
    // for the D runtime during linking.

    // In the future we might want to convert all functions in this module to
    // templates even for ordinary builds instead of providing them as an
    // extern(C) library.

    void onOutOfMemoryError()(void* pretend_sideffect = null) @nogc nothrow pure @trusted
    {
        assert(0, "Memory allocation failed");
    }
    alias onOutOfMemoryErrorNoGC = onOutOfMemoryError;

    void onInvalidMemoryOperationError()(void* pretend_sideffect = null) @nogc nothrow pure @trusted
    {
        assert(0, "Invalid memory operation");
    }
}
else
{
    /**
     * A callback for out of memory errors in D.  An $(LREF OutOfMemoryError) will be
     * thrown.
     *
     * Throws:
     *  $(LREF OutOfMemoryError).
     */
    extern (C) void onOutOfMemoryError(void* pretend_sideffect = null) @trusted pure nothrow @nogc /* dmd @@@BUG11461@@@ */
    {
        // NOTE: Since an out of memory condition exists, no allocation must occur
        //       while generating this object.
        throw staticError!OutOfMemoryError();
    }

    extern (C) void onOutOfMemoryErrorNoGC() @trusted nothrow @nogc
    {
        // suppress stacktrace until they are @nogc
        throw staticError!OutOfMemoryError(false);
    }
}

/**
 * A callback for invalid memory operations in D.  An
 * $(LREF InvalidMemoryOperationError) will be thrown.
 *
 * Throws:
 *  $(LREF InvalidMemoryOperationError).
 */
extern (C) void onInvalidMemoryOperationError(void* pretend_sideffect = null) @trusted pure nothrow @nogc /* dmd @@@BUG11461@@@ */
{
    // The same restriction applies as for onOutOfMemoryError. The GC is in an
    // undefined state, thus no allocation must occur while generating this object.
    throw staticError!InvalidMemoryOperationError();
}


/**
 * A callback for errors in the case of a failed fork in D.  A $(LREF ForkError) will be thrown.
 *
 * Params:
 *  file = The name of the file that signaled this error.
 *  line = The line number on which this error occurred.
 *
 * Throws:
 *  $(LREF ConfigurationError).
 */
extern (C) void onForkError( string file = __FILE__, size_t line = __LINE__ ) @trusted pure nothrow @nogc
{
    throw staticError!ForkError( file, line, null );
}

/**
 * A callback for unicode errors in D.  A $(LREF UnicodeException) will be thrown.
 *
 * Params:
 *  msg = Information about the error.
 *  idx = String index where this error was detected.
 *  file = The name of the file that signaled this error.
 *  line = The line number on which this error occurred.
 *
 * Throws:
 *  $(LREF UnicodeException).
 */
extern (C) void onUnicodeError( string msg, size_t idx, string file = __FILE__, size_t line = __LINE__ ) @safe pure
{
    throw new UnicodeException( msg, idx, file, line );
}

/***********************************
 * These functions must be defined for any D program linked
 * against this library.
 */
/+
extern (C) void onAssertError(string file, size_t line);
extern (C) void onAssertErrorMsg(string file, size_t line, string msg);
extern (C) void onUnittestErrorMsg(string file, size_t line, string msg);
extern (C) void onRangeError(string file, size_t line);
extern (C) void onHiddenFuncError(Object o);
+/

/***********************************
 * Function calls to these are generated by the compiler and inserted into
 * the object code.
 */

extern (C)
{
    /* One of these three is called upon an assert() fail.
     */
    void _d_assertp(immutable(char)* file, uint line)
    {
        import core.stdc.string : strlen;
        onAssertError(file[0 .. strlen(file)], line);
    }

    void _d_assert_msg(string msg, string file, uint line)
    {
        onAssertErrorMsg(file, line, msg);
    }

    void _d_assert(string file, uint line)
    {
        onAssertError(file, line);
    }

    /* One of these three is called upon an assert() fail inside of a unittest block
     */
    void _d_unittestp(immutable(char)* file, uint line)
    {
        import core.stdc.string : strlen;
        _d_unittest(file[0 .. strlen(file)], line);
    }

    void _d_unittest_msg(string msg, string file, uint line)
    {
        onUnittestErrorMsg(file, line, msg);
    }

    void _d_unittest(string file, uint line)
    {
        _d_unittest_msg("unittest failure", file, line);
    }

    /// Called when an invalid array index/slice or associative array key is accessed
    void _d_arrayboundsp(immutable(char*) file, uint line)
    {
        import core.stdc.string : strlen;
        onRangeError(file[0 .. strlen(file)], line);
    }

    /// ditto
    void _d_arraybounds(string file, uint line)
    {
        onRangeError(file, line);
    }

    /// Called when an out of range slice of an array is created
    void _d_arraybounds_slicep(immutable(char*) file, uint line, size_t lower, size_t upper, size_t length)
    {
        import core.stdc.string : strlen;
        onArraySliceError(lower, upper, length, file[0 .. strlen(file)], line);
    }

    /// ditto
    void _d_arraybounds_slice(string file, uint line, size_t lower, size_t upper, size_t length)
    {
        onArraySliceError(lower, upper, length, file, line);
    }

    /// Called when an out of range array index is accessed
    void _d_arraybounds_indexp(immutable(char*) file, uint line, size_t index, size_t length)
    {
        import core.stdc.string : strlen;
        onArrayIndexError(index, length, file[0 .. strlen(file)], line);
    }

    /// ditto
    void _d_arraybounds_index(string file, uint line, size_t index, size_t length)
    {
        onArrayIndexError(index, length, file, line);
    }
}

// TLS storage shared for all errors, chaining might create circular reference
private align(2 * size_t.sizeof) void[256] _store;

// only Errors for now as those are rarely chained
private T staticError(T, Args...)(auto ref Args args)
    if (is(T : Error))
{
    // pure hack, what we actually need is @noreturn and allow to call that in pure functions
    static T get()
    {
        static assert(__traits(classInstanceSize, T) <= _store.length,
                      T.stringof ~ " is too large for staticError()");

        return cast(T) _store.ptr;
    }
    auto res = (cast(T function() @trusted pure nothrow @nogc) &get)();
    import core.lifetime : emplace;
    emplace(res, args);
    return res;
}

// Suppress traceinfo generation when the GC cannot be used.  Workaround for
// Bugzilla 14993. We should make stack traces @nogc instead.
package class SuppressTraceInfo : Throwable.TraceInfo
{
    override int opApply(scope int delegate(ref const(char[]))) const { return 0; }
    override int opApply(scope int delegate(ref size_t, ref const(char[]))) const { return 0; }
    override string toString() const { return null; }
    static SuppressTraceInfo instance() @trusted @nogc pure nothrow
    {
        static immutable SuppressTraceInfo it = new SuppressTraceInfo;
        return cast(SuppressTraceInfo)it;
    }
}
