Change Log: 2.076.0 (upcoming)
Download D nightlies
To be released
Compiler changes
- AVX2 was added as -mcpu=avx2 architecture.
- Comparison of values belonging to different enums is deprecated.
- add __traits(getFunctionVariadicStyle, f)
- add __traits(getParameterStorageClasses, f, i)
- Deprecate empty statements made by semicolon
- The deprecated built-in array properties .sort and .reverse were removed.
Runtime changes
Library changes
- Several functions in std.string have been deprecated
- std.datetime has been split into a package.
- Added support for 64 bit CRC
- Added a constant time comparison function for cryptographic hashes
- std.digest.digest was renamed to std.digest.
- std.meta.Stride was added
- hasLength now enforces that length has type size_t
- std.range.slide (a fixed-size sliding window range) was added
List of all upcoming bug fixes and enhancements.
Compiler changes
- 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.
- Comparison of values belonging to different enums is deprecated.
This change does not affect anonymous enumerations.
enum Status { good, bad } enum OtherStatus { ok no, } // Deprecated - Even though both good and ok evaluate to 0 they belong to // different enumeration types static assert(Status.good == OtherStatus.ok);
- add __traits(getFunctionVariadicStyle, f)
import core.stdc.stdarg; void novar() {} extern(C) void cstyle(int, ...) {} extern(C++) void cppstyle(int, ...) {} void dstyle(...) {} void typesafe(int[]...) {} static assert(__traits(getFunctionVariadicStyle, novar) == "none"); static assert(__traits(getFunctionVariadicStyle, cstyle) == "stdarg"); static assert(__traits(getFunctionVariadicStyle, cppstyle) == "stdarg"); static assert(__traits(getFunctionVariadicStyle, dstyle) == "argptr"); static assert(__traits(getFunctionVariadicStyle, typesafe) == "typesafe"); static assert(__traits(getFunctionVariadicStyle, (int[] a...) {}) == "typesafe"); static assert(__traits(getFunctionVariadicStyle, typeof(cstyle)) == "stdarg");
- add __traits(getParameterStorageClasses, f, i)
ref int foo(return ref const int* p, scope int* a, out int b, lazy int c); pragma(msg, __traits(getParameterStorageClasses, foo, 0)); static assert(__traits(getParameterStorageClasses, foo, 0)[0] == "return"); static assert(__traits(getParameterStorageClasses, foo, 0)[1] == "ref"); pragma(msg, __traits(getParameterStorageClasses, foo, 1)); static assert(__traits(getParameterStorageClasses, foo, 1)[0] == "scope"); static assert(__traits(getParameterStorageClasses, foo, 2)[0] == "out"); static assert(__traits(getParameterStorageClasses, typeof(&foo), 3)[0] == "lazy");
- Deprecate empty statements made by semicolon
Creating empty statements using semicolons, for which was previously issued a warning is now causing a deprecation hint.
- The deprecated built-in array properties .sort and .reverse were removed.
Usage of those built-in array properties was deprecated since 2.072.0 and they have now been removed. Use std.algorithm.sorting.sort and std.algorithm.mutation.reverse instead.
Runtime changes
- Make fiber stack protection-page size configurable
It is now possible to change the guard page size by using the new Fiber's constructor argument - guard_page_size. It defaults to PAGE_SIZE (the same it used to be on Windows), and specifying 0 will turn this feature off.
- Add Fiber's stack-protection page for Posix.
The feature already existing for Windows' fiber implementation is now added to the systems using mmap to allocate fibers' stacks: After (or before) the last page used for the Fiber's stack, the page is allocate which is protected for any kind of access. This will cause system to trap immediately on the fiber's stack overflow.
- TypeInfo.init now refers to type property.
TypeInfo.init used to refer to the method that is now called TypeInfo.initializer. The name change was necessary because the name "init" would clash with the type property of the same name (init). TypeInfo.init now refers to the type property.
- Windows: the DATA and TLS segment can now be configured to be scanned precisely.
A new runtime option "scanDataSeg" has been added to enable precise scanning of the DATA and the TLS segments. This uses information generated by the compiler to identify possible pointers inside these segments. Possible option values are "conservative" (default) and "precise".
As usual, this option can be set by the environment, the command line or by embedding the option into the executable similar to the GC options.
For example add this code to your main module to enable precise scanning:
extern(C) __gshared string[] rt_options = [ "scanDataSeg=precise" ];
- Print unhandled exception's trace and abort if rt_trapExceptions is set
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
- Several functions in std.string have been deprecated
The functions std.string.inPattern, std.string.countchars, std.string.removechars, std.string.squeeze, and std.string.munch, have all been deprecated. These functions are obsolete, as their functionality is better covered by the functions in std.regex and std.algorithm. They will be removed from std.string on May 2018.
If you still need to use these, please see undeaD.
The following are examples of the deprecated functions, and their modern replacements.
Use std.algorithm.searching.find to replace std.string.munch:
import std.algorithm; import std.ascii; import std.string; import std.utf; string s = "\tabc"; // old s.munch(whitespace); // new s = s.find!(a => !isWhite(a));
Use std.regex.matchFirst to replace std.string.inPattern:
import std.string; import std.regex; // old if (inPattern('x', "a-z")) { ... } // new if ("x".matchFirst(regex("[a-z]"))) { ... }
Use std.regex.replaceAll to replace std.string.removechars:
import std.string; import std.regex; // old "abc".removechars("a-z"); // new "abc".replaceAll(regex("[a-z]"), "");
Use std.algorithm.iteration.uniq to replace std.string.squeeze:
import std.algorithm; import std.string; // old "hello".squeeze; // new "hello".uniq;
- std.datetime has been split into a package.
std.datetime is now a package containing the following modules:
- std.datetime.date
- std.datetime.interval
- std.datetime.stopwatch
- std.datetime.systime
- std.datetime.timezone
std.datetime.package publicly imports all of those modules. So, it should be the case that no existing code will break, as everything in std.datetime will still be imported by importing std.datetime. New code can choose to import the modules individually or to import the entire package.
std.datetime.date contains Date, TimeOfDay, DateTime, and the related free functions. It also contains DateTimeException.
std.datetime.interval contains the *Interval and *IntervalRange types as well as the related free functions.
std.datetime.systime contains SysTime and the related free functions.
std.datetime.timezone contains the time zone types.
std.datetime.package contains StopWatch and the benchmarking functions (so, they can only be imported via std.datetime and not via a submodule). As those functions use core.time.TickDuration (which is being replaced by core.time.MonoTime, they are slated for deprecation).
std.datetime.stopwatch has been added. It contains versions of StopWatch and benchmark which have almost the same API as the existing symbols, but they use core.time.MonoTime and core.time.Duration instead of core.time.TickDuration. In the next major release, the old functions in std.datetime.package will be deprecated, so code which uses the old benchmarking functions should be updated to use std.datetime.stopwatch.
However, note that in order to avoid irreconcilable symbol conflicts between the new and old versions, std.datetime.stopwatch will not be publicly imported by std.datetime.package until the old symbols have been removed. So, for the time being, code using std.datetime.stopwatch.StopWatch or std.datetime.benchmark.StopWatch will need to import std.datetime.stopwatch directly. Code which imports both std.datetime and std.datetime.stopwatch will need to either use selective imports or fully qualified symbols to reconcile the symbol conflicts, but no code will be affected by the changes until it's updated to import std.datetime.stopwatch, and when the old symbols are finally removed, the selective imports and fully qualified paths to the new symbols will continue to work and won't break (though at that point, simply importing std.datetime will work, since std.datetime.package will have been updated to publicly import std.datetime.stopwatch). Code that simply imporst std.datetime.stopwatch without importing std.datetime will not have to worry about symbol conflicts.
- Added support for 64 bit CRC
Support for both ISO and ECMA 64 bit CRC was added to std.digest.crc.
import std.digest.crc; void main() { ubyte[8] hash64ecma = crc64ECMAOf("abc"); assert(crcHexString(hash64ecma) == "2CD8094A1A277627"); ubyte[8] hash64iso = crc64ISOOf("abc"); assert(crcHexString(hash64iso) == "3776C42000000000"); }
- Added a constant time comparison function for cryptographic hashes
Added a new function to std.digest.digest.secureEqual that compares two ranges that represent hashes in a secure manner. The comparison is done in constant time regardless of the equality of the two ranges in order to protect against timing attacks. For more information on the attack, please refer to the docs on std.digest.digest.secureEqual.
import std.digest.digest : secureEqual, toHexString; import std.digest.hmac : hmac; import std.digest.sha : SHA1; import std.string : representation; void main() { // a typical HMAC data integrity verification auto secret = "A7GZIP6TAQA6OHM7KZ42KB9303CEY0MOV5DD6NTV".representation; auto data = "data".representation; string hex1 = data.hmac!SHA1(secret).toHexString; string hex2 = data.hmac!SHA1(secret).toHexString; string hex3 = "data1".representation.hmac!SHA1(secret).toHexString; assert( secureEqual(hex1, hex2)); assert(!secureEqual(hex1, hex3)); }
- 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)));
- hasLength now enforces that length has type size_t
Historically hasLength!R yielded true for types whereby R.length returns other types convertible to ulong, such as int, ushort, const(size_t), user-defined types using alias this, or notably ulong on 32-bit systems. This behavior has been deprecated. After December 2017, std.range.primitives.hasLength will yield true only if R.length yields the exact type size_t.
- std.range.slide (a fixed-size sliding window range) was added
std.range.slide allows to iterate a range in sliding windows:
import std.array : array; import std.algorithm.comparison : equal; assert([0, 1, 2, 3].slide(2).equal!equal( [[0, 1], [1, 2], [2, 3]] )); assert(5.iota.slide(3).equal!equal( [[0, 1, 2], [1, 2, 3], [2, 3, 4]] )); assert(iota(7).slide(2, 2).equal!equal([[0, 1], [2, 3], [4, 5]])); assert(iota(12).slide(2, 4).equal!equal([[0, 1], [4, 5], [8, 9]])); // set a custom stepsize (default 1) assert(6.iota.slide(1, 2).equal!equal( [[0], [2], [4]] )); assert(6.iota.slide(2, 4).equal!equal( [[0, 1], [4, 5]] )); // allow slide with less elements than the window size assert(3.iota.slide!(No.withFewerElements)(4).empty); assert(3.iota.slide!(Yes.withFewerElements)(4).equal!equal( [[0, 1, 2]] ));
List of all bug fixes and enhancements in D 2.076.0 (upcoming):
DMD Compiler regressions
- 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
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 16640: void fun(string file=__FILE_FULL_PATH__) returns relative path
- Bugzilla 17380: Compiler segfaults on undefined symbol
- 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)
DMD Compiler enhancements
- Bugzilla 9731: Ddoc should output per-paragraph macro instead of (DDOC_BLANKLINE)
- Bugzilla 17392: Add Dub file for the lexer and parser
- 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
Phobos regressions
- Bugzilla 17650: [REG v2.075.0 b1-b4] std.getopt range violation
Phobos bugs
- Bugzilla 6718: "nWayUnion" => "nWayMerge", plus true nWayUnion
- 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 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
Phobos enhancements
- 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
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
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"
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 17594: Define DDOC_BLANKLINE as an empty HTML paragraph, thus obviating the need to wrap text in (P ...)