Change Log: 2.080.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
- Argument mismatch errors have been improved
- The deprecation period of using the result of comma expression has ended
- Function parameters with default values are now allowed after variadic template parameters
- The delete keyword has been deprecated.
- The deprecation period of the -dylib flag on OSX has ended. Use -shared
- Experimental @nogc Exception throwing with -dip1008
- A compiler trait used to detect if a function is marked with @disable has been added.
- Fix Issue 17630 - selective imports find symbols in private imports of other modules
- Fix issue 17899 - Allow delegates to be initialised at compile time
- Fix Issue 18053 - mangle long/ulong as int64_t/uint64_t
- Fix Issue 18219 - Private import inside struct leaks symbols when used as VarDeclaration types
- Fix issue 18361 - Ddoc ability to opt-out of automatic keyword highlighting in running text
- D ABI change on Win32 and OSX targets
- HexString literals are deprecated.
- Added the -i command line option to automatically include imports
- Added -Xi=<name> to include more fields in the JSON output
- Lambda comparison using __traits(isSame, ...)
- Windows: Visual C++ and the Windows SDK are no longer required to build 64-bit executables
- Using D with no/minimal/custom runtime implementation in a pay-as-you-go fashion
- macOS deployment target was increased to 10.9
- Deprecate the use of selectively imported private members
- .ptr on arrays can no longer be used in @safe code
Runtime changes
List of all upcoming bug fixes and enhancements in D 2.080.0.
Compiler changes
- Argument mismatch errors have been improved
dmd now shows which argument failed to match a parameter with an explanatory error message.
void fill(ref char[16] buf, char c); void main() { fill("1234567890123456", '*'); const char[16] s; fill(s, '*'); }
Output:
fillchar.d(5): Error: function fillchar.fill(ref char[16] buf, char c) is not callable using argument types (string, char) fillchar.d(5): cannot pass rvalue argument "1234567890123456" of type string to parameter ref char[16] buf fillchar.d(8): Error: function fillchar.fill(ref char[16] buf, char c) is not callable using argument types (const(char[16]), char) fillchar.d(8): cannot pass argument s of type const(char[16]) to parameter ref char[16] buf
Note: Currently this change doesn't apply when the function has overloads.
- The deprecation period of using the result of comma expression has ended
Comma expressions have proven to be a frequent source of confusion, and bugs. Using their result will now trigger an error message.
The comma operator (,) allows executing multiple expressions and discards the result of them except for the last which is returned.
int a = 1; int b = 2; bool ret = a == 2, b == 2; // true
It's also common to use the comma operator in for-loop increment statements to allow multiple expressions.
for (; !a.empty && !b.empty; a.popFront, b.popFront)
Hence, using the comma operator in for-loop increment statements is still allowed.
Corrective Action
If possible, split the comma operator in two statements. Otherwise use lambdas.
auto result = foo(), bar(); // split off in two statements foo(); auto result = bar(); // or use lambdas auto result = {foo(); return bar();}();
Rationale
The comma operator leads to unintended behavior (see below for a selection) Moreover it is not commonly used and it blocks the ability to implement tuples as a language feature using commas.
A selection of problems through the accidental use of the comma operator:
writeln( 6, mixin("7,8"), 9 ); // 6, 8, 9 struct Vec { this(T...)(T args) { ... } } // missing type name Vec v = (0, 0, 3); // Vec(3) int a = 0; int b = 2; if (a == 1, b == 2) { // will always be reached } void foo(int x, int y=0) {} foo((a, b)); // Oops, foo(b) is called synchronized (lockA, lockB) {} // multiple expressions aren't currently implemented, but it compiles due to the comma operator
- Function parameters with default values are now allowed after variadic template parameters
Function parameters with default values are now allowed after variadic template parameters and when IFTI is used, always take their default values. This allows using special tokens (eg __FILE__) after variadic parameters, which was previously impossible.
For example:
string log(T...)(T a, string file = __FILE__, int line = __LINE__) { return text(file, ":", line, " ", a); } assert(log(10, "abc") == text(__FILE__, ":", __LINE__, " 10abc"));
This should be preferred to the previous workaround, which causes a new template instantiation for every invocation:
string log(string file = __FILE__, int line = __LINE__, T...)(T a);
- The delete keyword has been deprecated.
See the Deprecated Features for more information.
Starting with this release, using the delete keyword will result in a deprecation warning.
As a replacement, users are encouraged to use destroy if feasible, or core.memory.__delete as a last resort.
- The deprecation period of the -dylib flag on OSX has ended. Use -shared
The deprecation period of the -dylib flag on OSX has ended.
dmd -dylib awesome_d_library.d
Use the -shared flag to generate a shared library:
dmd -shared awesome_d_library.d
- Experimental @nogc Exception throwing with -dip1008
[DIP1008](https://github.com/dlang/DIPs/blob/master/DIPs/DIP1008.md) has been merged and it can be previewed under the experimental -dip1008 flag:
void main() @nogc { throw new Exception("I'm @nogc now"); }
rdmd -dip1008 app.d
- A compiler trait used to detect if a function is marked with @disable has been added.
Prior to this release is was impossible to filter out @disable functions without using __trait(compiles), which was less than ideal since false could be returned for other reasons.
Now, in metaprogramming code, @disable functions can be detected accurately, using __traits(isDisabled) and even in overload sets:
module runnable; struct Foo { import std.stdio; @disable static void foo() {__PRETTY_FUNCTION__.writeln;} static void foo(int v) {__PRETTY_FUNCTION__.writeln;} static void bar() {__PRETTY_FUNCTION__.writeln;} @disable static void bar(int v) {__PRETTY_FUNCTION__.writeln;} } void test(T)() { foreach (member; __traits(allMembers, T)) foreach (overload; __traits(getOverloads, T, member)) static if (!__traits(isDisabled, overload)) { static if (is(typeof(&overload) == void function())) overload(); else static if (is(typeof(&overload) == void function(int))) overload(42); } } void main(){test!Foo;}
prints:
void runnable.Foo.foo(int v) void runnable.Foo.bar()
- Fix Issue 17630 - selective imports find symbols in private imports of other modules
Selectively importing a symbol should work only if the symbol imported is defined or publicly imported in the imported module. Due to a compiler bug, selectively importing a symbol works even if the symbol is defined in a privately imported module in the imported module.
//a.d int bar; //b.d import a; //c.d import b : bar;
The above code will now result in a deprecation message which states that bar cannot be accessed since it is privately imported in b.
- Fix issue 17899 - Allow delegates to be initialised at compile time
delegates may now be initialised at module scope. This changes the effect of the fix for 13259 (turning the ICE that resulted into an error) making the follow legal:
void delegate() bar = (){};
The function pointer is set to the function of the delegate, the context pointer is set to null.
- Fix Issue 18053 - mangle long/ulong as int64_t/uint64_t
This is a breaking change (on OSX 64).
Due to the erratic implementation defined behavior of C++ name mangling, it was difficult to get D's long/ulong to portably match up with the corresponding C++ compiler.
By instead relying on how the corresponding C++ compiler mangled int64_t/uint64_t it makes the C++ side of the D<=>C++ interface much simpler.
For the current platforms dmd supports, only the OSX 64 bit mangling changes. In this case from 'm' to 'y'.
Note: int64_t and uint64_t are defined in stdint.h
- Fix Issue 18219 - Private import inside struct leaks symbols when used as VarDeclaration types
When implementing a struct which has a local private import the imported symbols are leaked if present in a VarDeclaration statement. For more information and examples see : https://issues.dlang.org/show_bug.cgi?id=18219
Symbols from the private import should not visible outside the struct scope. A deprecation is now issued when such cases are encountered
- Fix issue 18361 - Ddoc ability to opt-out of automatic keyword highlighting in running text
Currently, ddoc automatically highlights all occurrences of words in running text that coincide with the symbol or module being documented, or a parameter name of a function being documented. While convenient, it often caused unintended highlighting of normal words in text when module, function, or parameter identifiers coincide with normal words. This led to a proliferation of prefixing words with _ in order to suppress this behaviour.
Now a better solution has been implemented to completely opt-out of this feature via the DDOC_AUTO_PSYMBOL, DDOC_AUTO_KEYWORD, and DDOC_AUTO_PARAM macros, which are used for all such automatically-highlighted words in running text. Occurrences of module, function, or parameter names inside code blocks are not included. By default, these macros simply redirect to DDOC_PSYMBOL, DDOC_KEYWORD, and DDOC_PARAM, but the user can now redefine these macros so that they simply expand to the word itself without any highlighting:
DDOC_AUTO_PSYMBOL = DDOC_AUTO_KEYWORD = DDOC_AUTO_PARAM =
Furthermore, whenever a word is prefixed with _ to suppress automatic highlighting, it is now wrapped in the DDOC_AUTO_PSYMBOL_SUPPRESS macro. This is to provide users who wish to opt out of automatic highlighting an easy way to find all occurrences of these underscore prefixes so that they can be removed from the text. For example, they can redefine this macro to something highly-visible and easily searched for, such as:
DDOC_AUTO_PSYMBOL_SUPPRESS = FIXME_UNDERSCORE_PREFIX
and then search the generated documentation for the string FIXME_UNDERSCORE_PREFIX and delete the _ prefix from all corresponding parts of the documentation comment text.
- D ABI change on Win32 and OSX targets
The compiler has been updated to prefix all extern(D) symbols with an extra underscore where the platform expects one on all external symbols. This allows compiled code to work better with binutil programs, such as the ability to list symbols demangled inside a debugger.
This is an ABI breaking change and requires recompiling libraries.
- HexString literals are deprecated.
HexString literals are deprecated. Use std.conv.hexString instead.
- Added the -i command line option to automatically include imports
Added the command line option -i which causes the compiler to treat imported modules as if they were given on the command line. The option also accepts "module patterns" that include/exclude modules based on their name. For example, the following will include all modules whose names start with foo, except for those that start with foo.bar:
dmd -i=foo -i=-foo.bar
The option -i by itself is equivalent to:
dmd -i=-std -i=-core -i=-etc -i=-object
- Added -Xi=<name> to include more fields in the JSON output
Added -Xi=<name> to include more fields in the JSON output. Currently there are 4 fields that can be included: "compilerInfo", "buildInfo", "modules" and "semantics", i.e.
dmd -Xi=compilerInfo -Xi=buildInfo -Xi=semantics -Xi=modules
will generate a JSON file with the following:
{ "compilerInfo" : { "binary" : "<filename-of-compiler-binary>", "version" : "<compiler-version>", "supportsIncludeImports" : true, }, "buildInfo" : { "config" : "<config-filename>", "cwd" : "<cwd-during-build>", "importParths" : [ "<import-path1>", "<import-path2>", // ... ] }, "semantics" : { "modules" : [ { "name" : "<module-name>", "file" : "<module-filename>", "isRoot" : true|false }, // more module objects... ] }, "modules" : [ // an array of the syntax data for all the modules, // this is the same array that would be generated // for a JSON file with no -Xi=<field> options ] }
If JSON is generated without any -Xi= options then the old format is used. The old format is the same data that would appear in the new "modules" field.
Also note that the compiler can now be invoked with no source files as long as at least one JSON field is provided, i.e.
dmd -Xi=compilerInfo
This is an experimental command-line flag and will be stabilized in the next release.
- Lambda comparison using __traits(isSame, ...)
It is now possible to compare two lambda functions, under certain constraints, using __traits(isSame, lamda1, lambda2). In order to correctly compare two lambdas, the following conditions must be satisfied:
- the lambda function arguments must not have a template instantiation as an explicit argument type. Any other argument types (basic, user-defined, template) are supported.
- the lambda function body must contain a single expression (no return statement) which contains only numeric values, manifest constants, enum values and arguments. If the expression contains local variables, function calls or return statements, the function is considered uncomparable.
These limitations might be lifted in the next release version.
Whenever a lambda is considered uncomparable, the __traits(isSame, ...) expression in which it's used will return false, no matter what other lambda is used in the comparison.
- Windows: Visual C++ and the Windows SDK are no longer required to build 64-bit executables
The Windows installer now adds platform libraries built from the MinGW definitions and a wrapper library for the VC2010 shared C runtime. When building COFF object files with -m64 or -m32mscoff and no Visual Studio installation is detected or no platform libraries are found these will be used as replacements. If the Microsoft linker is not found, the LLVM linker LLD will be used.
- Using D with no/minimal/custom runtime implementation in a pay-as-you-go fashion
DMD has been further decoupled from the runtime so it is now easier and more convenient to use D without the runtime in a pay-as-you-go fashion. This will be of interest to users wishing to incrementally or partially port D to new platforms, users targeting bare-metal or resource constrained platforms, and users wishing to use D as a library from other languages without the runtime.
Prior to this release, if one attempted to compile a simple D application that made no use of any runtime features, the compiler would have emitted a number of errors about a missing object.d, a missing Error class, missing TypeInfo, and missing ModuleInfo, among others.
Starting with this release, one can now create a library for use from another language, requiring only the .d source file that implements that library, and an empty object.d file
Example 1
module object
module math; extern(C) int add(int a, int b) { return a + b; }
dmd -conf= -lib math.d size math.a text data bss dec hex filename 0 0 0 0 0 math.o (ex math.a) 20 0 0 20 14 math_1_129.o (ex math.a)
Also, starting with this release, one can now create very small executables with a minimal runtime implementation.
Example 2
DMD auto-generates a call to _d_run_main which, in turn, calls the user-defined main function. DMD automatically generates a call to g++ which links in the C runtime.
module object; private alias extern(C) int function(char[][] args) MainFunc; private extern (C) int _d_run_main(int argc, char** argv, MainFunc mainFunc) { return mainFunc(null); // assumes `void main()` for simplicity }
module main; void main() { }
dmd -conf= -defaultlib= -fPIC main.d object.d -of=main size main text data bss dec hex filename 1403 584 16 2003 7d3 main
Example 3
Manually generated call to main. No C runtime.
module object; extern(C) void __d_sys_exit(long arg1) { asm { mov RAX, 60; mov RDI, arg1; syscall; } } extern void main(); private extern(C) void _start() { main(); __d_sys_exit(0); }
module main; void main() { }
dmd -c -lib main.d object.d -of=main.o ld main.o -o main size main text data bss dec hex filename 56 0 0 56 38 main
Usage of more advanced D features (e.g. classes, exceptions, etc...) will require runtime implementation code, but they can be implemented in a pay-as-you-go fashion.
- macOS deployment target was increased to 10.9
The compiler has been updated to use 10.9 and link with libc++ on OSX. This is due the shared libstdc++ library from older versions of macOS having compatibility issues with the headers included in a modern XCode.
The minimum required version of running the compiler is now Mac OS X Mavericks (10.9).
- Deprecate the use of selectively imported private members
The specification states that a private member is visible only from within the same module. Prior to this release, due to a bug, private members were visible through selective imports from other modules, violating the specification. Beginning with this release, accessing private members from outside the module in which they are declared will result in a deprecation message.
- .ptr on arrays can no longer be used in @safe code
The deprecation period for using .ptr on arrays in @safe ended. The following now triggers an error instead of a deprecation:
@safe ubyte* oops(ubyte[] arr) { return arr.ptr; }
Use &arr[0] instead:
@safe ubyte* oops(ubyte[] arr) { return &arr[0]; }
Note that this only applies to SafeD - in @system code .ptr may still be used:
@system ubyte* oops(ubyte[] arr) { return arr.ptr; }
Runtime changes
- core.memory.__delete has been added
core.memory.__delete allows easy migration from the deprecated delete. __delete behaves exactly like delete:
bool dtorCalled; class B { int test; ~this() { dtorCalled = true; } } B b = new B(); B a = b; b.test = 10; __delete(b); assert(b is null); assert(dtorCalled); // but be careful, a still points to it assert(a !is null);
For example, on a Posix platform you can simply run:
sed "s/delete \(.*\);/__delete(\1);/" -i **/*.d
Users should prefer object.destroy` to explicitly finalize objects, and only resort to core.memory.__delete when object.destroy would not be a feasible option.
- The garbage collector is now lazily initialized on first use
The runtime now lazily initializes the GC on first use, thus allowing applications that do not use the GC to skip its initialization.
Library changes
- std.typecons.BitFlags now supports opDispatch-based property access
std.typecons.BitFlags was extended so that enum members can be set and tested directly on the BitFlags instead of having to & with the underlying enum.
enum Features { fast = 1 << 0, size = 1 << 1, } void run(BitFlags!Features features) { // get if (features.fast && !features.size) {} // new new new if ((features & Features.fast) && !(features & Features.size)) {} // old old old // set features.fast = true; // new new new features.fast = false; // new new new features.fast |= Features.fast; // old old old features.fast &= ~Features.fast; // old old old }
This also works for unsafe BitFlags where the property get access tests for an exact match of all bits of the unsafe BitFlags combination. Analogously, the property set access clears or sets all bits of the unsafe BitFlags combination.
enum Features { fast = 1 << 0, size = 1 << 1, combined = fast | size, } void run(BitFlags!(Features, Yes.unsafe) features) { // get if (features.combined) {} // new new new if ((features & Features.combined) == BitFlags!(Features, Yes.unsafe)(Features.combined)) {} // old old old // set features.combined = true; // new new new features.combined = false; // new new new features.combined |= Features.combined; // old old old features.combined &= ~Features.combined; // old old old }
List of all bug fixes and enhancements in D 2.080.0:
DMD Compiler regressions
- Bugzilla 16243: wrong C++ argument passing with empty struct when interfacing with Clang
DMD Compiler bugs
- Bugzilla 5212: no escape analysis for typesafe variadic function arguments
- Bugzilla 9433: Deprecate delete
- Bugzilla 15653: IFTI fails for immutable parameter
- Bugzilla 16555: Stack corruption when calling multi-parameter outer function from nested function
- Bugzilla 16578: bogus deprecation - switch skips declaration of variable
- Bugzilla 17284: Template function attribute inference wrongly infers @safe for accessing overlapping pointer fields in unions
- Bugzilla 17892: Scope analysis with -dip1000 fails for templated structs
- Bugzilla 17959: [DIP1000] Can store scope delegate in non-scope member
- Bugzilla 18000: [scope] auto-generated opAssign not scope aware
- Bugzilla 18505: delete deprecation message is misleading
- Bugzilla 18575: making delegate from member function can lead to unsafe code
- Bugzilla 18576: Compiler not doing RVO with auto returns
DMD Compiler enhancements
- Bugzilla 16037: assigning delegate to a scope variable shouldn't allocate closure
- Bugzilla 18460: Improve error message for missing 'new' for class instantiation
- Bugzilla 18503: Confusing error message for erroneous postblit
- Bugzilla 18551: Improve hint for "does not override any function
- Bugzilla 18574: Unclear error message when trying to inherit from multiple classes
- Bugzilla 18591: DMD should allow access to mixin template declarations
Phobos regressions
- Bugzilla 17961: std.uni does not compile with -unittest -dip1000
- Bugzilla 18565: std.regex Captures opAssign returns void since v2.079.0
Phobos bugs
- Bugzilla 7879: format of class with not const toString()
- Bugzilla 13642: std.container.Array: change of length reallocates without notifying GC
- Bugzilla 18133: BitArray constructors are poorly documented.
- Bugzilla 18134: BitArray >>= broken when length % (8 * size_t.sizeof) == 0
- Bugzilla 18524: std.range.Zip.moveBack instead performs moveFront
- Bugzilla 18548: [2.079] std.format ignores templated toString if another toString is not a template
- Bugzilla 18579: No group separators for floating point number formatted with zero decimal digits
Phobos enhancements
- Bugzilla 8341: topN(zip()) too?
- Bugzilla 10828: datetime toString functions should accept sink
- Bugzilla 18158: std.file.getcwd should be usable in @safe
- Bugzilla 18166: std.array.replace should be usable in @safe for dstrings
- Bugzilla 18168: std.base64.encode for output ranges should be usable in @safe
- Bugzilla 18182: std.uri should be usable in @safe
- Bugzilla 18501: randomShuffle and partialShuffle should return their input argument
Druntime bugs
- Bugzilla 18482: wincrypt functions should be @nogc nothrow
- Bugzilla 18536: Bad stack traces when building with -m32mscoff
- Bugzilla 18537: Cannot pass absolute path to coverage options
- Bugzilla 18547: Win32: throwing exception in fiber crashes application
Contributors to this release (42)
A huge thanks goes to all the awesome people who made this release possible.
- Alexandru Caciulescu
- Alexandru Jercaianu
- Andrei Alexandrescu
- Basile Burg
- Brad Roberts
- byebye
- carblue
- cedretaber
- Denis Feklushkin
- Diederik de Groot
- drug007
- Iain Buclaw
- Jack Stouffer
- Jacob Carlborg
- Jan Jurzitza
- Joakim Noah
- Johan Engelen
- Jonathan M Davis
- Jonathan Marler
- Kai Nacke
- kinke
- Martin Kinkelin
- Martin Nowak
- MetaLang
- Mike Franklin
- Mike Parker
- Nathan Sashihara
- Nicholas Lindsay Wilson
- Nick Treleaven
- Oleg Nykytenko
- Radu Racariu
- Rainer Schuetze
- Razvan Nitu
- Ryan Frame
- Sebastian Wilzbach
- skl131313
- Steven Schveighoffer
- Thomas Mader
- Timothee Cour
- Vladimir Panteleev
- Walter Bright
- Ľudovít Lučenič