The D Language Foundation is pleased to present version 2.084.0 of DMD, the reference D compiler. It’s available for download at dlang.org, where you can also find the full changelog. There are a few changes and new features to be found, as usual, along with 100 closed Bugzilla issues this time around.
Finer Control Over Run-time Checks
The new compiler flag -check
is a feature that grew out of DIP 1006 and some internal discussions around its content. The flag allows overriding the default behavior of six specific categories of run-time checks by specifically turning them on
or off
:
assert
– assertion checksbounds
– bounds checksin
–in
contractsinvariant
– class and struct invariantsout
–out
contractsswitch
– default switch cases
For example, when compiling without -release
, all run-time checks are enabled by default. To disable only assertion checks:
dmd -check=assert=off foo.d
This can be further refined with the new -checkaction
flag, which determines how the program will respond when an assertion, bounds, or switch check fails. There are four options: D
, C
, and halt
.
D
– the default D behavior, which is to throw anError
to indicate an unrecoverable condition.C
– behave as a C program by calling the assertion failure function in the C runtime.halt
– execute a halt instruction to terminate the program.
Listed in the language documentation is a fourth option: context
. This causes failed checks to throw an Error
to indicate an unrecoverable condition, and also print the error context. It isn’t present in this release, but is coming in DMD 2.085 (the online documentation is generated from the DMD master branch).
Save Your Mixins
One of D’s most popular and powerful features is the mixin
statement, commonly referred to as string mixins to avoid confusion with template mixins. Unfortunately, given that string mixins can be composed from multiple compile-time function calls, they are also notoriously painful to debug as they grow in complexity. The new -mixin
compiler option aims to do away with that pain.
Consider the following simple (contrived) example, which attempts to generate a function call with a string mixin:
import std.stdio; void hello() { writeln("Hello!"); } void main() { mixin(hello.stringof ~ "();"); }
Save as hello.d
, compile with dmd hello
, and you’ll see an error along these lines:
hello.d-mixin-6(6): Error: function expected before (), not hello() of type void
The error does say exactly what the problem is, but even in this simple case it may require re-reading the message a few times before working out what it’s actually saying. So let’s recompile with the -mixin
flag. It requires a file name. I’ve selected mixed.txt
:
dmd -mixin=mixed.txt hello.d
Now we see this output:
mixed.txt(110): Error: function expected before (), not hello() of type void
See the difference? The error now refers to a line number in a file with the name we provided, rather than a line in the autogenerated hello.d-mixin-6
to which we couldn’t refer. Open mixed.txt
and navigate to line 110 to find the generated code, along with a comment at line 109:
// expansion at foo.d(6) hello()();
And now the error is quite clear. Invoking .stringof
on a function provides you with the function name including the parentheses, so there’s no need to append parentheses to the result. We can now change the example so that it will compile:
void main() { mixin(hello.stringof ~ ";"); }
Anyone making significant use of string mixins to generate code will undoubtedly find this feature useful. It will be particularly helpful for the maintainers of D-friendly IDEs and plugins to make the user experience more convenient.
New DUB features
DMD 2.084.0 ships with version 1.13.0 of DUB, the D build tool and package manager. It gets some new goodies with this release.
The new add
command is a convenience to add dependencies to a project’s package recipe. No need to worry about the syntax and whether the recipe is written using JSON or SDLang. Simply run dub with the add
command, specifying one or more dub packages, and the recipe will be modified accordingly. For example, to add the BindBC bindings for the GLFW and OpenGL C libraries:
dub add bindbc-glfw bindbc-opengl
This will add the latest version of each library. This can be restricted to a specific version by appending =
to the package name along with the normal DUB syntax for version specifications. This can also be used to change the version specification of an existing dependency.
For those unfamiliar with DUB, executing dub run
, or simply dub
, in a directory containing a dub recipe will build a project according to the recipe and, if the project is an executable, run it once the build completes. Now, there are two new recipe directives that can be used to achieve more specialized goals. preRunCommands
specifies commands to execute before the DUB target is run, and postRunCommands
specifies commands to execute when the run is complete. See the DUB package recipe documentation for the JSON syntax or the SDLang syntax, under “Build Settings” in each, to see what they look like.
That’s Not All
Regarding the 100 closed Bugzilla issues, two points should be made.
First is that among many of the Pull Request merges that closed those issues, you’ll find Nicholas Wilson’s GitHub handle. Nicholas is, of course, the community member the D Language Foundation asked to serve as PR Manager, to be paid through a fundraising campaign. He’s been reviving old PRs and making sure new ones don’t go stale. This release is evidence that the initiative is paying off. And the icing on the cake is that the D community enabled us to meet our fundraising target well before our February 14th deadline. Thanks!
Second, a point relevant to the #dbugfix campaign. While I was disappointed that participation in nominating Bugzilla issues on Twitter and in the Forums dwindled to near zero, the previous nominations were not forgotten. The original goal was to fix at least two nominated issues per cycle, so several nominated bugs were never selected. However, thanks to Eduard Staniloiu and Razvan Nitu, two among that group are now closed and fixed in this release:
- #13300 – pure function ‘std.array.Appender!(T[]).Appender.ensureAddable’ cannot call impure function ‘test.T.__fieldPostBlit’,
- #18572 – AliasSeq default arguments are broken
I’m still happy to take #dbugfix nominations. If you’ve got a Bugzilla issue that’s bugging you, tweet a link to it with #dbugfix in the text, or start a thread in the General forum with #dbugfix in the title. I’ll make a note of it and, rather than counting votes and selecting two of the top five, see if I can find someone to do something about it.