Change Log: 2.083.0
Download D nightlies
To be released
This changelog has been automatically generated from all commits in master since the last release.
- The full-text messages are assembled from the changelog/ directories of the respective repositories: dmd, druntime, phobos, tools, dlang.org, installer, and dub.
- See the DLang-Bot documentation for details on referencing Bugzilla. The DAutoTest PR preview doesn't include the Bugzilla changelog.
- The pending changelog can be generated locally by setting up dlang.org and running the pending_changelog target:
make -f posix.mak pending_changelog
Compiler changes
- Support for comparing arrays of unsigned byte-sized types and structs has been added to -betterC
- Added D_ModuleInfo, D_Exceptions, and D_TypeInfo version identifiers
- Deprecate conditional expression followed by an assign expression
- Unsafe code can now be used in debug blocks
- Deprecate usage of opDot
- D now supports deprecated, @disable and user-defined attributes on enum members
- Deprecated C-style array declarations will now result in a compilation error
- Mangling of extern(C++) template on Windows now correctly mangles const non-pointer template parameters.
- .offsetof and .tupleof for fields of Objective-C classes have now been disabled
- 64-bit OS X: Revert C++ mangling of long to pre-2.079 to restore size_t interop
- UDAs on function parameters are now supported
Runtime changes
Library changes
- Single- and double-precision implementations for (a)tan and exp function families
- std.algorithm.iteration.each is now capable of early-stopping
- std.algorithm.iteration.joiner can now be used for bidirectional ranges
- std.algorithm.searching.skipOver can now handle variadic arguments
- Added staticArray to construct a static array from array / input range. Includes a length-inferring compile-time variant.
- Deprecated functions for getting the timezone have been removed.
Installer changes
List of all upcoming bug fixes and enhancements in D 2.083.0.
Compiler changes
- Support for comparing arrays of unsigned byte-sized types and structs has been added to -betterC
Prior to this release, the following code did not build in -betterC, but will with this release.
// (Prior to this release) Error: TypeInfo cannot be used with -betterC struct Sint { int x; this(int v) { x = v;} } extern(C) void main() { Sint[6] a1 = [Sint(1), Sint(2), Sint(3), Sint(1), Sint(2), Sint(3)]; assert(a1[0..3] == a1[3..$]); }
// (Prior to this release) Linker Error: undefined reference to `core.internal.string.dstrcmp` extern(C) void main() { auto s = "abc"; switch(s) { case "abc": break; default: break; } }
// (Prior to this release) Linker Error: undefined reference to `core.internal.string.dstrcmp` extern(C) void main() { char[6] a = [1,2,3,1,2,3]; assert(a[0..3] >= a[3..$]); // failed for any byte-sized type (e.g. `char`, `ubyte`, etc...) }
- Added D_ModuleInfo, D_Exceptions, and D_TypeInfo version identifiers
D_ModuleInfo, D_Exceptions, and D_TypeInfo version identifiers were added to allow better precision in druntime and other library implementations.
- Deprecate conditional expression followed by an assign expression
When a conditional expression is the left operand of an assign expression, they would be parsed as an assignment to the result of the conditional. This has now been deprecated. To preserve the existing behaviour, add parentheses for the conditional without including the assignment:
bool test; int a, b, c; ... test ? a = b : c = 2; // Deprecated (test ? a = b : c) = 2; // Equivalent
This makes the intent clearer, because the first statement can easily be misread as the following code:
test ? a = b : (c = 2);
- Unsafe code can now be used in debug blocks
When writing debug code, one isn't interested in the type safety, but a pleasant debugging experience. The type checker already allowed to escape pure and @nogc within debug statement. With this release, @system code can be called from debug statements too:
void main() { int[] arr = [1, 2]; debug unsafeCode(arr); } @system void unsafeCode(T)(T[] arr) { import core.stdc.stdio; printf("arr.ptr: %p", arr.ptr); }
- Deprecate usage of opDot
opDot was the D1 analog to alias this. However, alias this covers all use cases of opDot, but ensures safety.
struct S { int a, b; } struct T { S s; S* opDot() { return &s; } } void main() { T t; t.a = 4; assert(t.a == 4); t.b = 5; }
With alias this:
struct S { int a, b; } struct T { S s; alias s this; } void main() @safe { T t; t.a = 4; assert(t.a == 4); t.b = 5; }
- D now supports deprecated, @disable and user-defined attributes on enum members
Example
template AliasSeq(TList...) { alias AliasSeq = TList; } enum MyEnum { @("uda0") value0, @disable value1, deprecated value2 // Deprecation: enum member `main.MyEnum.value2` is deprecated } static assert(__traits(getAttributes, MyEnum.value0) == AliasSeq!("uda0")); void main() { auto v1 = MyEnum.value1; // Error: enum member `main.MyEnum.value1` cannot be used because it is annotated with `@disable` }
- Deprecated C-style array declarations will now result in a compilation error
The deprecation period for C-style array declarations has expired. Beginning with this release, declaring arrays with C-style syntax will result in an error.
int a[2]; // Error: instead of C-style syntax, use D-style `int a[2]` int[2] b; // OK
- Mangling of extern(C++) template on Windows now correctly mangles const non-pointer template parameters.
It used to ignore the const and was missing the $$C escape prefix.
extern(C++) struct foo(T) {} extern(C++) void test(foo!(const(char)) a) {} // New static assert(test.mangleof == "?test@@YAXU?$foo@$$CBD@@@Z"); // Old //static assert(test.mangleof == "?test@@YAXU?$foo@D@@@Z");
- .offsetof and .tupleof for fields of Objective-C classes have now been disabled
To solve the fragile base class problem [1] in Objective-C, fields have a dynamic offset instead of a static offset. The compiler outputs a statically known offset which later the dynamic loader can update, if necessary, when the application is loaded. Due to this behavior it doesn't make sense to be able to get the offset of a field at compile time, because this offset might not actually be the same at runtime.
To get the offset or value of a field, that is correct at runtime, functionality from the Objective-C runtime can be used instead [2].
[1] https://en.wikipedia.org/wiki/Fragile_binary_interface_problem [2] https://developer.apple.com/documentation/objectivec/objective_c_runtime
- 64-bit OS X: Revert C++ mangling of long to pre-2.079 to restore size_t interop
Direct interop of D size_t and C++ size_t was working before 2.079, on all platforms except for 32-bit OS X. By mangling D long as C++ long long on 64-bit OS X starting with 2.079, size_t interop broke on a more relevant platform. With new/fixed aliases, e.g., core.stdc.stdint.int64_t, core.stdc.stdint.uint64_t and core.stdc.config.cpp_size_t, there are now proper tools for portable C++ interop wrt. integers. Reverting to the previous C++ mangling on 64-bit OS X (C++ long) may save mixed D/C++ code bases from the need of manual adaptations by skipping the 2.079-2.081 DMD versions.
- UDAs on function parameters are now supported
User-defined attributes on function parameters behave analogous to existing UDAs:
void example(@(22) string param) { @(11) string var; static assert([__traits(getAttributes, var)] == [11]); static assert([__traits(getAttributes, param)] == [22]); }
Runtime changes
- Exception trapping can now be disabled via --DRT-trapExceptions=0
Previously it was only possible to disable the trapping of exception by setting the global variable rt_trapExceptions to false. Now you can, for example, immediately open gdb at the uncaught exception:
> gdb -ex run --args
--DRT-trapExceptions=0 [Thread debugging using libthread_db enabled] Using host libthread_db library "/usr/lib/libthread_db.so.1". uncaught exception object.Exception@src/rt_trap_exceptions_drt.d(4): foo –––––––––– src/rt_trap_exceptions_drt.d:4 void rt_trap_exceptions_drt.test() [0x55591026] src/rt_trap_exceptions_drt.d:9 _Dmain [0x55591058] Program received signal SIGABRT, Aborted. 0x00007ffff6e7b86b in raise () from /usr/lib/libc.so.6 (gdb) bt full #0 0x00007ffff6e7b86b in raise () from /usr/lib/libc.so.6 No symbol table info available. #1 0x00007ffff6e6640e in abort () from /usr/lib/libc.so.6 No symbol table info available. #2 0x00005555555918cc in _d_throwdwarf (o=0x7ffff7ea4000) at src/rt/dwarfeh.d:233 eh = 0x7ffff7fa4740 refcount = 0 r = 5 #3 0x0000555555591027 in rt_trap_exceptions_drt.test() () at ../../src/object.d:2695 innerLocal = 20 #4 0x0000555555591059 in D main (args=...) at src/rt_trap_exceptions_drt.d:9 myLocal = "bar" This Week in D for an in-depth explanation of rt_trapExceptions
- Additional functions for associative arrays
The require function provides a means to construct a new value when the key is not present.
class C{} C[string] aa; auto a = aa.require("a", new C); // lookup "a", construct if not present
The update function allows different operations to be performed depending on whether a value already exists or needs to be constructed.
class C{} C[string] aa; C older; C newer; aa.update("a", { newer = new C; return newer; }, (ref C c) { older = c; newer = new C; return newer; });
The functions avoid the need to perform multiple key lookups. Further details are available in the spec.
- TypeInfo.getHash now uses core.internal.hash.hashOf functions for hash computing
Now typeid(typeof(var)).getHash(&var) should be always equal hashOf(val). hashOf uses MurmurHash3 algorithm for bitwise hashing, including string hashing. Old implementation used polynomial hash for string hashing, which often provided lexicographical order of strings in associative array. However AA doesn't guarantee some specific order of elements, thus tests which rely on it should be changed.
- core.sys.posix.utsname.update renamed to version_
The struct that uname returns - utsname - has the field version in C. The D definition of the struct cannot match that, because version is a keyword in D. So, it's been called update, which is not an obvious choice. It is more in line with current naming policies (and more in line with the name in C) for it to be called version_, since that's the closest that we can get to version in D. So, update has now been renamed to version_, and update is an alias of version_ which will be deprecated in a future release.
Library changes
- Single- and double-precision implementations for (a)tan and exp function families
The float and double overloads of std.math.atan, std.math.atan2, std.math.tan, std.math.exp, std.math.expm1 and std.math.exp2 previously forwarded to the real implementation (inline assembly) and now got proper 'software' implementations in the corresponding precision.
While this may result in a slowdown in some cases for DMD (especially for exp() and exp2()), the overall speed-up factor for LDC is > 3, for both double and float.
This also implies less precise results, especially in single-precision, so if your code depended on more accurate results via 80-bit intermediate precision, you'll have to cast the argument(s) explicitly now.
- std.algorithm.iteration.each is now capable of early-stopping
std.algorithm.iteration.each is now capable of exiting early. When a No.each std.typecons.Flag is returned from the function that is called by each, the iteration will be aborted early. Analogously, returning Yes.each will continue the iteration. For example:
auto arr = [10, 20, 30]; arr.each!((n) { arr ~= n; return (n == 20) ? No.each : Yes.each; }); // aborts after the second iteration assert(arr == [10, 20, 30, 10, 20]);
- std.algorithm.iteration.joiner can now be used for bidirectional ranges
std.algorithm.iteration.joiner can now be requested to be a bidirectional range.
import std.algorithm.iteration : joiner; import std.range : retro; [[1, 2], [3, 4]].joiner.retro; // [4, 3, 2, 1]
A more complex example of inserting a format delimiter fully lazily:
import std.algorithm.comparison : equal; import std.range : chain, cycle, iota, only, retro, take, zip; import std.format : format; static immutable number = "12345678"; static immutable delimiter = ","; auto formatted = number.retro .zip(3.iota.cycle.take(number.length)) .map!(z => chain(z[0].only, z[1] == 2 ? delimiter : null)) .joiner .retro; // "12,345,678"
- std.algorithm.searching.skipOver can now handle variadic arguments
std.algorithm.skipOver which allows to move over a needle if it matches now accepts variadic arguments for needles to skip over:
auto s = "DLang.rocks"; assert(!s.skipOver("dlang", "DLF", "DLang ")); assert(s == "DLang.rocks"); assert(s.skipOver("dlang", "DLANG", "DLF", "D", "DL", "DLanp")); assert(s == "ang.rocks");
- Added staticArray to construct a static array from array / input range. Includes a length-inferring compile-time variant.
The type of elements can be specified implicitly so that [1, 2].staticArray results in int[2], or explicitly, e.g. [1, 2].staticArray!float returns float[2]. When a is a range whose length is not known at compile time, the number of elements must be given as template argument (e.g. myrange.staticArray!2). Size and type can be combined, if the source range elements are implicitly convertible to the requested element type (eg: 2.iota.staticArray!(long[2])). When the range a is known at compile time, it can also be specified as a template argument to avoid having to specify the number of elements (e.g.: staticArray!(2.iota) or staticArray!(double, 2.iota)).
import std.range : iota; auto input = 3.iota; auto a = input.staticArray!2; static assert(is(typeof(a) == int[2])); assert(a == [0, 1]); auto b = input.staticArray!(long[4]); static assert(is(typeof(b) == long[4])); assert(b == [0, 1, 2, 0]);
- Deprecated functions for getting the timezone have been removed.
Due to the fact that Microsoft changes its timezone definitions too frequently to maintain the conversion between the IANA TZ Database names and the names that Microsoft uses in the standard library, several functions in std.datetime.timezone related to getting the time zone independently of the host OS were previously deprecated: TimeZone.getTimeZone, TimeZone.getInstalledTZNames, tzDatabaseNameToWindowsTZName, and windowsTZNameToTZDatabaseName. These functions have now been fully removed.
Instead of TimeZone.getTimeZone, std.datetime.timezone.PosixTimeZone.getTimeZone and std.datetime.timezone.WindowsTimeZone.getTimeZone should be used directly. Instead of Timezone.getInstalledTimeZones, std.datetime.timezone.PosixTimeZone.getInstalledTZNames and std.datetime.timezone.WindowsTimeZone.getInstalledTZNames should be used directly. And any programs looking to convert between the TZ Database names and the Windows names can use std.datetime.timezone.parseTZConversions with the current windowsZones.xml file to get the current conversions (see the documenation for std.datetime.timezone.parseTZConversions for details).
Installer changes
- Windows installer and binaries are now code-signed
All released executables on Windows will now be code-signed by the following certificate.
Issuer: C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert SHA2 Assured ID Code Signing CA Serial Number: 04:e7:49:06:78:3a:e6:5f:54:37:fd:55:45:66:5f:e5 Validity Not Before: Aug 7 00:00:00 2018 GMT Not After : Aug 11 12:00:00 2021 GMT Subject: C = US, ST = Washington, L = Kirkland, O = D Language Foundation, CN = D Language Foundation SHA1 Fingerprint: BD:E0:0F:CA:EF:6A:FA:37:15:DB:D4:AA:1A:43:2E:78:27:54:E6:60 SHA256 Fingerprint: AA:B0:6F:7B:A8:26:52:51:C4:24:44:1B:34:8E:30:68:F4:34:DB:35:38:6A:17:A7:45:C3:27:77:11:24:C4:E5
Nightly builds and branch/feature previews will not be code-signed for now.
List of all bug fixes and enhancements in D 2.083.0:
DMD Compiler regressions
- Bugzilla 19219: Could not CTFE with std.math.exp from 2.082.0
- Bugzilla 19243: [REG 2.081] Can no longer override pragma(lib) with -L switch
- Bugzilla 19248: Wrong mangle for C++ const STL classes/structs
- Bugzilla 19266: Some source files names are no longer accepted
- Bugzilla 19304: [Reg 2.081.0] Linker arguments order changed in issue 15574 hinders using --whole-archive linker directive
DMD Compiler bugs
- Bugzilla 11538: [ICE] stack overflow with recursive NullableRef fails
- Bugzilla 14246: RAII - proper destruction of partially constructed objects/structs
- Bugzilla 15374: [internal] Nothing should import ddmd.mars
- Bugzilla 18457: betterC - struct destructor is always called at function return
- Bugzilla 18771: Identical overload sets in different modules have different identities
- Bugzilla 18955: extern(C++) default struct mangling is overridden when interacting with a cppmangle = class template
- Bugzilla 19098: Improve error for non-assignable struct
- Bugzilla 19181: Semantic errors in opDispatch argument lead to "no property X"
- Bugzilla 19182: missing semicolon crashes compiler
- Bugzilla 19185: [ICE] Nested struct segfaults when using variable from outer scope
- Bugzilla 19209: [ICE] Overriding a field in a baseclass issues an ICE
- Bugzilla 19225: Confusing error message on static else
- Bugzilla 19251: Alias this does not get called on struct qualified type
- Bugzilla 19284: alias this not used in nested functions of a method
DMD Compiler enhancements
- Bugzilla 15512: extern(C++, ns) should consider taking a string
- Bugzilla 19180: Expose dmd.mtype.Type.isZeroInit as __traits(isZeroInit, T)
- Bugzilla 19194: version for -mscrtlib specification
- Bugzilla 19195: Support pragma to specify linker directives
- Bugzilla 19199: Use core.bitops intrinsics during CTFE
- Bugzilla 19203: alias this to a bool behaves both inconsistently and incorrectly with static assert
- Bugzilla 19212: Add versions for C++ runtimes.
- Bugzilla 19292: Mixin expressions should take an argument list the same as pragma(msg) does
Phobos regressions
- Bugzilla 19252: Templated format with variable width allocates 2GB of RAM per call.
Phobos bugs
- Bugzilla 11431: std.file.slurp fails with Windows newlines
- Bugzilla 11959: Phobos should not declare public symbols in version(unittest) blocks
- Bugzilla 17276: BaseClassesTuple fails on extern C++ classes that implement an interface without a base class
- Bugzilla 18675: std.experimental.checkedint.Checked has opEquals but no toHash
- Bugzilla 18683: std.containers.rbtree.RedBlackTree has opEquals but no toHash
- Bugzilla 18838: Formatting the number zero with separator doesn't obey width specifier
- Bugzilla 18851: std.net.curl.post cannot be used with !ubyte
- Bugzilla 19085: std.experimental.allocator.makeArray should work with void
- Bugzilla 19200: Variant operators don't overload correctly
- Bugzilla 19207: std.algorithm.subsitute wrong results for single subrange substitution
- Bugzilla 19228: hasAliasing fails on static arrays
- Bugzilla 19240: std.typecons.Tuple should check for reserved identifiers
- Bugzilla 19275: std.process: redirecting output in a non-console application fails
- Bugzilla 19289: std.range.transposed with enforceNotJagged not throwing
- Bugzilla 19297: JSONValue of signed and unsigned equal values is not equal
Phobos enhancements
- Bugzilla 18142: checkedint opOpAssign doesn't accept a checkedint
- Bugzilla 19236: Replace runtime typeid(T).initializer().ptr is null checks with compile-time __traits(isZeroInit, T)
- Bugzilla 19257: std.array.join does not handle const fields that cannot be converted to mutable
Druntime bugs
- Bugzilla 19250: DWARF Backtraces with very long symbol names read out of bounds when printing
- Bugzilla 19262: hashOf associative array should infer nothrow
- Bugzilla 19282: hashOf segfaults for non-null C++ objects
- Bugzilla 19314: Thread object destruction may result in UB
Druntime enhancements
- Bugzilla 19280: Remove unnecessary error checks in core.time.currSystemTick and currTime
dlang.org bugs
- Bugzilla 18104: Alias example compiles where it states that it should be illegal
Contributors to this release (53)
A huge thanks goes to all the awesome people who made this release possible.
- 0xEAB
- aG0aep6G
- Alexandru ermicioi
- Andrei Alexandrescu
- Arun Chandrasekaran
- Basile Burg
- BBasile
- Carsten Schlote
- devel
- deviator
- dhasenan
- Diederik de Groot
- Dragos Carp
- Erik van Velzen
- Eugen Wissner
- GoaLitiuM
- Iain Buclaw
- Ilya Yaroshenko
- Ionut
- Joakim Noah
- Johannes Loher
- Johannes Pfau
- John Colvin
- Jonathan M Davis
- kinke
- look-at-me
- Manu Evans
- Martin Nowak
- Mathias Lang
- Mathis Beer
- Mihails Strasuns
- Mike Franklin
- Mike Parker
- Márcio Martins
- Nathan Sashihara
- Nicholas Lindsay Wilson
- Nicholas Wilson
- Petar Kirov
- Pjotr Prins
- Rainer Schuetze
- Razvan Nitu
- Remi Thebault
- Ryan David Sheasby
- Sebastian Wilzbach
- shove70
- Simen Kjærås
- Steven Schveighoffer
- Thomas Mader
- Vlad Vitan
- Vladimir Panteleev
- Walter Bright
- wolframw
- Ľudovít Lučenič