Skip to content
This repository was archived by the owner on Oct 12, 2022. It is now read-only.
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 16 additions & 24 deletions src/core/lifetime.d
Original file line number Diff line number Diff line change
Expand Up @@ -2648,16 +2648,19 @@ if (!Init.length ||
}

/**
* Allocate an exception of type `T` from the exception pool and call its constructor.
* It has the same interface as `rt.lifetime._d_newclass()`.
* `T` must be Throwable or derived from it, must declare an explicit ctor
* and cannot be a COM or C++ class.
* Allocate an exception of type `T` from the exception pool.
* `T` must be `Throwable` or derived from it and cannot be a COM or C++ class.
*
* Note:
* This function does not call the constructor of `T` because that would require
* `forward!args`, which causes errors with -dip1008. This inconvenience will be
* removed once -dip1008 works as intended.
*
* Returns:
* constructed instance of the type
* allocated instance of type `T`
*/
T _d_newThrowable(T, Args...)(auto ref Args args) @trusted
if (is(T : Throwable) && is(typeof(T.__ctor(forward!args))) &&
__traits(getLinkage, T) == "D")
T _d_newThrowable(T)() @trusted
if (is(T : Throwable) && __traits(getLinkage, T) == "D")
{
debug(PRINTF) printf("_d_newThrowable(%s)\n", cast(char*) T.stringof);

Expand Down Expand Up @@ -2687,33 +2690,22 @@ T _d_newThrowable(T, Args...)(auto ref Args args) @trusted

(cast(Throwable) p).refcount() = 1;

auto t = cast(T) p;
t.__ctor(forward!args);

return t;
return cast(T) p;
}

@system unittest
{
class E : Exception
{
int x;

this(int x, string msg = "", Throwable nextInChain = null)
this(string msg = "", Throwable nextInChain = null)
{
super(msg, nextInChain);
this.x = x;
}
}

auto exc = _d_newThrowable!Exception("Exception");
assert(exc.refcount() == 1);
assert(exc.msg == "Exception");

static assert(!__traits(compiles, _d_newThrowable!E()));
Throwable exc = _d_newThrowable!Exception();
Throwable e = _d_newThrowable!E();

auto e = _d_newThrowable!E(42, "E", null);
assert(exc.refcount() == 1);
assert(e.refcount() == 1);
assert(e.x == 42);
assert(e.msg == "E");
}