Change Log: 2.076.0
Download D 2.076.0
released Sep 01, 2017
Compiler changes
Library changes
- Base64URLNoPadding (URL-safe Base64 without padding) was added
- std.digest.digest was renamed to std.digest.
- std.meta.Stride was added
- Config.detached flag for spawnProcess has been added
- std.range.chunks was extended to support non-forward input ranges.
- std.socket.UnixAddress now supports abstract addresses.
- Added possibility to use a baseclass when auto-implementing an interface
List of all bug fixes and enhancements in D 2.076.0.
Compiler changes
- Implement DIP 1010 - Static foreach
Support for static foreach has been added.
static foreach is a conditional compilation construct that is to foreach what static if is to if. It is a convenient way to generate declarations and statements by iteration.
import std.conv: to; static foreach(i; 0 .. 10) { // a `static foreach` body does not introduce a nested scope // (similar to `static if`). // The following mixin declaration is at module scope: mixin(`enum x` ~ to!string(i) ~ ` = i;`); // declares 10 variables x0, x1, ..., x9 } import std.range: iota; // all aggregate types that can be iterated with a standard `foreach` // loop are also supported by static foreach: static foreach(i; iota(10)) { // we access the declarations generated in the first `static foreach` pragma(msg, "x", i, ": ", mixin(`x` ~ to!string(i))); static assert(mixin(`x` ~ to!string(i)) == i); } void main() { import std.conv: text; import std.typecons: tuple; import std.algorithm: map; import std.stdio: writeln; // `static foreach` has both declaration and statement forms // (similar to `static if`). static foreach(x; iota(3).map!(i => tuple(text("x", i), i))) { // generates three local variables x0, x1 and x2. mixin(text(`int `,x[0],` = x[1];`)); scope(exit) // this is within the scope of `main` { writeln(mixin(x[0])); } } writeln(x0," ",x1," ",x2); // first runtime output }
- -betterC enhancements
Many improvements were added to the dmd's -betterC implementation, most notably programs compiled with -betterC will no longer reference unused druntime symbols, asserts are implemented as C <assert.h> calls, and phobos is not linked by default.
See the Better C specs for more details.
- AVX2 was added as -mcpu=avx2 architecture.
This allows the backend to emit AVX2 instructions. The compiler will add the predefined version D_AVX2. AVX2 support is automatically detected with -mcpu=native.
- -betterC enhancements
Many improvements were added to the dmd's -betterC implementation, most notably programs compiled with -betterC will no longer reference unused druntime symbols, asserts are implemented as C <assert.h> calls, and phobos is not linked by default.
See the Better C specs for more details.
- Fix Issue 17697 - Ddoc: automatically highlight URLs outside of macro arguments
URLs which appear in Ddoc text:
/**** * http://www.fooa.com/test1 */
will be treated as if they were written:
/**** * $(LINK http://www.fooa.com/test1) */
and a clickable hyperlink will be emitted to the resulting .html file.
This detection does not happen if the URL is part of a macro argument:
/**** * $(DOLLAR)$(LPAREN)ABC http://www.fooa.com/test1$(RPAREN) */
The behavior of that is unchanged. URLs can start with http:// or https://
http: and https: at the beginning of the line are no longer treated as section headings.
- Implement DIP 1010 - Static foreach
Support for static foreach has been added.
static foreach is a conditional compilation construct that is to foreach what static if is to if. It is a convenient way to generate declarations and statements by iteration.
import std.conv: to; static foreach(i; 0 .. 10) { // a `static foreach` body does not introduce a nested scope // (similar to `static if`). // The following mixin declaration is at module scope: mixin(`enum x` ~ to!string(i) ~ ` = i;`); // declares 10 variables x0, x1, ..., x9 } import std.range: iota; // all aggregate types that can be iterated with a standard `foreach` // loop are also supported by static foreach: static foreach(i; iota(10)) { // we access the declarations generated in the first `static foreach` pragma(msg, "x", i, ": ", mixin(`x` ~ to!string(i))); static assert(mixin(`x` ~ to!string(i)) == i); } void main() { import std.conv: text; import std.typecons: tuple; import std.algorithm: map; import std.stdio: writeln; // `static foreach` has both declaration and statement forms // (similar to `static if`). static foreach(x; iota(3).map!(i => tuple(text("x", i), i))) { // generates three local variables x0, x1 and x2. mixin(text(`int `,x[0],` = x[1];`)); scope(exit) // this is within the scope of `main` { writeln(mixin(x[0])); } } writeln(x0," ",x1," ",x2); // first runtime output }
Runtime changes
- Print unhandled exception's trace and abort if rt_trapExceptions is false
D exception handling was assuming the top level exception handler, so all exceptions would be handled somewhere. In case rt_trapExceptions is cleared, this handler would not be enabled, and this assertion would fail, aborting the program, but without any information about the exception. This is now changed, so the exception information will be printed to the stderr, followed by abort.
Library changes
- Base64URLNoPadding (URL-safe Base64 without padding) was added
std.base64.Base64URLNoPadding allows encoding/decoding without padding:
import std.base64 : Base64URLNoPadding; ubyte[] data = [0x83, 0xd7, 0x30, 0x7b, 0xef]; assert(Base64URLNoPadding.encode(data) == "g9cwe-8"); assert(Base64URLNoPadding.decode("g9cwe-8") == data);
- std.digest.digest was renamed to std.digest.
Motivation:
The fully qualified name of the digest function template was std.digest.digest.digest. This is because std.digest is a package, with a module named digest in it, and the function digest inside that.
std.digest contains the former std.digest.digest package.
- std.meta.Stride was added
std.meta.Stride allows selecting a subset of template by a step size and offset:
alias attribs = AliasSeq!(short, int, long, ushort, uint, ulong); static assert(is(Stride!(3, attribs) == AliasSeq!(short, ushort))); static assert(is(Stride!(3, attribs[1 .. $]) == AliasSeq!(int, uint)));
- Config.detached flag for spawnProcess has been added
Config.detached allows spawning processes which run independently from the current process. There is no need to wait on the processes created with this flag, and no zombie process will be left after they exit. Attempts to call std.process.wait or std.process.kill on detached processes will throw.
- std.range.chunks was extended to support non-forward input ranges.
Now std.range.chunks can be used with input ranges that are not forward ranges, albeit with limited semantics as imposed by the underlying range.
import std.algorithm.comparison : equal; int i; // The generator doesn't save state, so it cannot be a forward range. auto inputRange = generate!(() => ++i).take(10); // We can still process it in chunks, but it will be single-pass only. auto chunked = inputRange.chunks(2); assert(chunked.front.equal([1, 2])); assert(chunked.front.empty); // Iterating the chunk has consumed it chunked.popFront; assert(chunked.front.equal([3, 4]));
- std.socket.UnixAddress now supports abstract addresses.
UNIX domain sockets are usually identified by pathnames. Linux offers a non-portable extension to this scheme, known as abstract socket addresses, which are independent of the filesystem. An abstract socket address starts with a null byte ('\0'), e.g.:
auto addr = new UnixAddress("\0/tmp/dbus-OtHLWmCLPR");
- Added possibility to use a baseclass when auto-implementing an interface
A second std.typecons.AutoImplement template has been added, which differs from the existing one in accepting an extra type parameter. The extra parameter specifies a class to derive from while auto-implementing an interface.
The base class used may contain non-default constructors. Matching constructors will be created in the auto-implemented class and be implemented as just a call to super with all arguments.
Tools changes
- rdmd now checks for a D compiler binary in the directory it's in first
If you downloaded a zip/tar file with the compiler before and ran rdmd, it would invoke the D compiler from the system PATH rather than the compiler right next to it, failing if there wasn't one in the PATH. rdmd will now try to use the D compiler next to it first, and only fall back to the PATH if there isn't one adjacent. If you want rdmd to run a specific compiler, add the --compiler flag to force it, as always.
To restore the old behaviour of only using the compiler from your PATH, add --compiler=dmd (or ldmd2 or gdmd).
List of all bug fixes and enhancements in D 2.076.0:
DMD Compiler regressions
- Bugzilla 16680: dmd doesn't use druntime optimized versions of subtraction array operations
- Bugzilla 17522: win64.mak broken
- Bugzilla 17582: [REG2.059] Applying const to struct declaration should make the struct type const
- Bugzilla 17612: [REG2.063] Segmentation fault with bad object.d
- Bugzilla 17684: [REG 2.062] static alias this bug or incomplete implementation?
- Bugzilla 17690: [REG2.066.0] scope guards leak declarations
- Bugzilla 17695: [Reg 2.076] ICE with vector negation
- Bugzilla 17761: [REG2.075] dmd 2.075.1 creates object files that can't be linked by ld.bfd
DMD Compiler bugs
- Bugzilla 4014: CodeView debug type info not linked in from library
- Bugzilla 11881: -betterC switch suffers from bit rot
- Bugzilla 11997: rdmd should search its binary path for the compiler
- Bugzilla 13512: Allow non-UTF-8 encoding in shebang line
- Bugzilla 15432: Win64: bad code offset in debug line number info
- Bugzilla 16640: void fun(string file=__FILE_FULL_PATH__) returns relative path
- Bugzilla 17380: Compiler segfaults on undefined symbol
- Bugzilla 17388: [scope] e[] should be treated like &e as far as scope goes
- Bugzilla 17430: [scope] delegate can escape context ptr
- Bugzilla 17484: high penalty for vbroadcastsd with -mcpu=avx
- Bugzilla 17489: ICE in ddmd/argtypes.d
- Bugzilla 17551: VC build: bad mangling of real template argument
- Bugzilla 17629: package.di files cannot be used
- Bugzilla 17660: ICE with static foreach: AssertError@ddmd/visitor.d(39)
- Bugzilla 17688: ICE with static foreach directly inside switch
- Bugzilla 17689: finally clause leaks declarations
- Bugzilla 17721: Wrong expression type using vector extensions with shift operands
- Bugzilla 17722: Wrong diagnostic using __traits(compiles, e1 && e2) expressions.
- Bugzilla 17735: AssertError@ddmd/target.d(357): unhandled op using fish operators
DMD Compiler enhancements
- Bugzilla 9287: DMD should read from stdin when an input file is "-"
- Bugzilla 9731: Ddoc should output per-paragraph macro instead of (DDOC_BLANKLINE)
- Bugzilla 17392: Add Dub file for the lexer and parser
- Bugzilla 17428: [scope] class field assignment allows to escape scope parameters
- Bugzilla 17499: with -betterC switch, call C's assert failure function rather than druntime's
- Bugzilla 17521: -betterC programs should not link in Phobos runtime library by default
- Bugzilla 17590: Unnecessary GC alloc on returning static local struct
- Bugzilla 17697: Ddoc: automatically highlight URLs outside of macro arguments
Phobos regressions
- Bugzilla 17650: [REG v2.075.0 b1-b4] std.getopt range violation
- Bugzilla 17661: New isInputRange rejects valid input range
- Bugzilla 17724: digest is not a template declaration, it is a module
Phobos bugs
- Bugzilla 6718: "nWayUnion" => "nWayMerge", plus true nWayUnion
- Bugzilla 12260: Improve error of std.stdio.readf when involving whitespace
- Bugzilla 12866: Append to std.container.Array of fixed size arrays
- Bugzilla 16079: memoize should cache objects too
- Bugzilla 16191: std/digest/digest.d should be renamed to package.d
- Bugzilla 17389: std.traits.hasNested fails for class with member of same type
- Bugzilla 17458: [std.regex] Assertion failure in package.d
- Bugzilla 17539: std.parallellism.parallel triggers 'statement not reachable' warnings in the rdmd_test suite
- Bugzilla 17562: Tangent function returns NaN for abs(input) >= 2^63
- Bugzilla 17574: Range violation in std.getopt:getopt AA parsing
- Bugzilla 17616: makeIndex cannot fully use range of index type
- Bugzilla 17640: std.concurrenct writeln conflicts with std.stdio writeln in unittests
- Bugzilla 17673: wrong whichPattern in multi-regex with alteration
- Bugzilla 17711: std.array.byPair should be usable with const AA
- Bugzilla 17780: Malformed DDOC links in std.range
Phobos enhancements
- Bugzilla 2137: Data not compressed on fly when adding to zip archive
- Bugzilla 6384: std.traits.isComparable
- Bugzilla 15759: chunks should work with only an input range
- Bugzilla 15771: FileLogger should create the output directory if it does not exist
- Bugzilla 16062: Add 'clear' method to OutBuffer (std.outbuffer)
- Bugzilla 16993: Documentation for toSimpleString and toString does not explain how they differ
- Bugzilla 17250: ProcessPipes (std.process) should provide a test for a null pid
- Bugzilla 17365: https://dlang.org/phobos/std_experimental_checkedint.html is missing the Throw hook description
- Bugzilla 17369: [Module std.traits] Documentation lists ditto in table
- Bugzilla 17525: std.algorithm.searching.skipOver should have a single argument with pred version
- Bugzilla 17540: std.net.curl: HTTP no possibillity to set CURLOPT_NOPROXY
- Bugzilla 17587: JSONOptions: No forward slash encoding
Druntime regressions
- Bugzilla 15619: [REG 2.066] Floating-point x86_64 codegen regression, when involving array ops
Druntime bugs
- Bugzilla 11594: synchronized causing segfault instead of Error.
- Bugzilla 14319: core.demangle does not support member function attributes
- Bugzilla 14563: core.demangle: Does not demangle type modifers
- Bugzilla 14576: [ddemangle] core.demangle unable to handle ambiguity in symbols
- Bugzilla 16856: D does not work on FreeBSD current (what will eventually be 12) due to libunwind
- Bugzilla 17609: core.demangle demangles delegate variables as functions
- Bugzilla 17610: core.demangle shows return type of template alias parameter
- Bugzilla 17611: core.demangle cannot demangle delegates with function attributes
- Bugzilla 17624: typo in Fields documentation section of https://dlang.org/library/object/exception.html
- Bugzilla 17665: Win64 atomicLoad for T[] cannot be cast from size_t[2]
Druntime enhancements
- Bugzilla 16664: core.demangle functions are not callable from @safe or pure code
dlang.org bugs
- Bugzilla 17159: Behavior of unions at compile time is not documented
- Bugzilla 17224: Foreach documentation still refers to TypeTuples, rather than AliasSequences
- Bugzilla 17305: [SPEC] ABI page still has references to D1 Phobos
- Bugzilla 17509: [typo] "refered to" ("referred to")
- Bugzilla 17510: How could 509 be a byte value?
- Bugzilla 17513: [english] "a enum" -> "an enum"
- Bugzilla 17702: codemirror hangs firefox for several seconds
dlang.org enhancements
- Bugzilla 13153: dlang.org: provide version-specific documentation of the language and stdlib
- Bugzilla 17262: Better docs for rdmd
- Bugzilla 17322: Add Magikcraft to organizations using D
- Bugzilla 17480: [Downloads]
- Bugzilla 17524: [The C Preprocessor vs D] "need to worry about"?
- Bugzilla 17560: Enhancement: view and copy full code example for offline compile/play
- Bugzilla 17581: Document behavior of -betterC
- Bugzilla 17594: Define DDOC_BLANKLINE as an empty HTML paragraph, thus obviating the need to wrap text in (P ...)
Tools bugs
- Bugzilla 17731: dman fails to build due to more than 32767 symbols