Hi,
This week I finished converting _d_newThrowable
to a template, as well as its lowering in the compiler. The PRs for these are:
Also this week, I fixed the bug when compiling the new lowering for a ~= b
to either _d_arrayappendcTX
or _d_arrayappendT
. It turned out it was because of how $
is evaluated by the compiler. The initial lowering when b
was a single element looked like this:
__ctfe ? a ~= b : _d_arrayappendcTX(a, 1), a[$ - 1] = b, a;
When a chain of concatenations (like (a ~= b) ~= c
) was lowered, in order for (a ~= b)
to not be executed 3 times, I saved the result in a temporary variable, before concatenating c
to it.
When this kind of expression was inlined, the $
was mishandled by the compiler, which resulted in an incorrect ArrayIndexError
. To solve this issue, I used a.length
instead of $
. Now the lowering looks like this:
__ctfe ? a ~= b : _d_arrayappendcTX(a, 1), a[a.length - 1] = b, a;
// Note that the assignment above is actually a construction.
The PR that changes the lowering is: https://github.com/dlang/dmd/pull/13495.
A point of contention is the fact that I lower a ~= b
to a CondExp
. As I explained here, I believe this is the more elegant approach, despite being more complex.
Another issue was that because the current template _d_arrayappendcTX
uses a temporary implementation that calls the old hook using a mixin.
For this reason, the new hook is always impure and has to be declared pure
so it can pass semantic analysis from pure
contexts.
_d_arrayappendT
also calls _d_arrayappendcTX
and, hence, is declared pure
as well. However, _d_arrayappendT
also calls copyEmplace
, which can sometimes be impure
. This causes an error when trying to instantiate _d_arrayappendT
. To bypass this, I created an impure
private function in DRuntime, which is called _d_arrayappendT
after being made pure
via a cast. This way, _d_arrayappendT
appears pure when it needs to be, but is also able to call an impure copyEmplace
when it has to.
The implementation of this hack is here: https://github.com/dlang/druntime/pull/3662.
Keep in mind that this is a hack for a stop-gap hook. In the future, I intend to change the implementation of _d_arrayappendcTX
so that it won't call the old hook anymore and thus allow attributes such as pure
, nothrow
etc to be inferred by the compiler.
Thanks,
Teodor