Change Log: 2.112.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
- Storage classes ref and auto ref can now be applied to local, static, extern, and global variables
- Keywords auto and ref must be adjacent
- The align attribute now allows specifying default explicitly
- Remove delete as a keyword
- Case fallthough for multivalued cases is an error now
- An error is now given for constructors when a field's destructor has stricter attributes
- Initializing a field with itself has been deprecated
- An error is now given for subtracting pointers of different types
- An error is now issued for in/out contracts of nothrow functions that may throw
- Typesafe variadic class parameters have been deprecated
- Integers in debug or version statements have been removed from the language
- Many error messages have changed
- The compiler now accepts -extern-std=c++23
- Build time profiling has been added to DMD
- New traits getBitfieldOffset and getBitfieldWidth for built-in bitfields
- Using the compiler flag -i will now properly pick up C source files
- A pragma for ImportC allows to set nothrow, @nogc or pure
- Mixin templates can now use assignment syntax
- Object file extensions .o and .obj are now accepted on all platforms
- Objective-C selectors are now automatically generated when not specified with @selector.
- New compiler switch -oq for DMD
- Added Placement New Expression
- Postfix type qualifier method attributes for -H and -D
- The folder samples has been removed from DMD installations
- New keyword __rvalue
- Add -preview=safer switch for safety checking on unattributed functions
- Shortened method syntax can now be used in constructors
Runtime changes
Library changes
- Added std.conv.bitCast
- Extend the functionality of formattedRead to permit a std.file.slurp like execution.
- Added fromHexString and fromHexStringAsRange functions to std.digest.
- ODBC Bindings in etc.c.odbc have been updated to ODBC 4.0.
- Added popGrapheme function to std.uni.
- Added readfln and File.readfln to std.stdio
- Added the SharedAllocatorList, as the thread-safe version of the regular AllocatorList.
- New procedural API for std.sumtype
- std.uni has been upgraded from Unicode 15.1.0 to 16.0.0
List of all upcoming bug fixes and enhancements in D 2.112.0.
Compiler changes
- Storage classes ref and auto ref can now be applied to local, static, extern, and global variables
For example, one can now write:
struct S { int a; } void main() { S s; ref int r = s.a; r = 3; assert(s.a == 3); auto ref x = 0; auto ref y = x; static assert(!__traits(isRef, x)); static assert( __traits(isRef, y)); }
- Keywords auto and ref must be adjacent
It's now deprecated to declare auto ref parameters without putting those two keywords next to each other. This way it's clear that auto ref semantics are intended, rather than ref and auto semantics separately. For the newly introduced ref local / global variables, it's an error immediately.
void t()(ref const auto int x) // Deprecation { ref auto y = x; // Error } // Correction: void t()(auto ref const int x) { auto ref y = x; }
- The align attribute now allows specifying default explicitly
A lone align sets the alignment to the type’s default. To be more explicit, align(default) does the same.
struct S { align(4) { byte x; align(default) long y; long z; } } void main() { pragma(msg, S.x.alignof); // 4 pragma(msg, S.y.alignof); // 8 pragma(msg, S.z.alignof); // 4 }
- Remove delete as a keyword
After being superseded by destroy(), deprecated, and turned into an error, delete can now be used as an identifier:
enum Action { add, delete } void delete(T)(T obj) { }
- Case fallthough for multivalued cases is an error now
This used to give a deprecation and now gives an error:
int i; switch (0) { case 0, 1: i = 20; default: assert(0); // Error: switch case fallthrough - use 'goto default;' if intended } switch (0) { default: case 0, 1: i = 20; case 2, 3: i = 30; // Error: switch case fallthrough - use 'goto case;' if intended }
- An error is now given for constructors when a field's destructor has stricter attributes
struct HasDtor { ~this() {} } struct Pure { HasDtor member; this(int) pure {} // Error: `this` has stricter attributes than its destructor (`pure`) } struct Nothrow { HasDtor member; this(int) nothrow {} // Error: `this` has stricter attributes than its destructor (`nothrow`) } struct NoGC { HasDtor member; this(int) @nogc {} // Error: `this` has stricter attributes than its destructor (`@nogc`) } struct Safe { HasDtor member; this(int) @safe {} // Error: `this` has stricter attributes than its destructor (`@safe`) }
- Initializing a field with itself has been deprecated
This is to prevent a common mistake when a field and a parameter ought to have the same name, but one is misspelled where it's declared:
struct S { int field; this(int feild) // supposed to be: this(int field) { this.field = field; // equal to this.field = this.field } }
- An error is now given for subtracting pointers of different types
The following code now gives errors:
static assert(cast(void*)8 - cast(int*) 0 == 2L); static assert(cast(int*) 8 - cast(void*)0 == 8L); void test() { auto foo = (ushort*).init - (ubyte*).init; }
- An error is now issued for in/out contracts of nothrow functions that may throw
This used to issue a deprecation, it is now an error:
void test() nothrow in { throw new Exception(null); // Error: `in` contract may throw but function is marked as `nothrow` } out { throw new Exception(null); // Error: `out` contract may throw but function is marked as `nothrow` } do { }
- Typesafe variadic class parameters have been deprecated
This obscure feature allowed a limited form of implicit construction:
void check(bool x, Exception e...) { if (!x) throw e; } void main(string[] args) { check(args.length > 1, "missing argument"); }
However, few uses of this feature have been found, and one project was actually mistakenly using it instead of the more common Typesafe variadic array parameter. Considering D doesn't support implicit construction and already has a confusing amount of different variadic parameter forms, it was decided to remove this feature.
As a corrective action, either call the constructor in the callee:
void check(string msg) { if (!x) throw new Exception(msg); }
Or let the caller construct the class instance:
void check(bool x, Exception e); void main(string[] args) { check(args.length > 1, new Exception("missing argument")); }
- Integers in debug or version statements have been removed from the language
These were deprecated in 2.101. Use -debug=identifier and -version=identifier instead for versions set on the command line, and likewise version = identifier; and debug = identifier; for versions set in code at global scope.
- Many error messages have changed
Some changes have been made without being associated to a reported issue:
Error messages for @safe violations now consistently mention they are related to @safe functions (or default functions with -preview=safer). In general, function attributes that failed to infer have a more compact error message:
Before:
app.d(8): Error: function attributediagnostic_nothrow.gc1 is not nothrow app.d(2): which wasn't inferred nothrow because of: app.d(2): object.Exception is thrown but not caught
After:
app.d(8): Error: function attributediagnostic_nothrow.gc1 is not nothrow app.d(2): and object.Exception being thrown but not caught makes it fail to infer nothrow
Function literals are now referred to by their (truncated) function body, instead of the internal __lambda name.
/* BEFORE: ../test/test_.d(3): Error: function literal `__lambda1()` is not callable using argument types `(int)` (() => 42)(1); ^ AFTER: ../test/test_.d(3): Error: function literal `() => 42` is not callable using argument types `(int)` (() => 42)(1); ^ */Match levels are now mentioned on ambiguous overloads: #20637
Before:
Error: app.bar called with argument types (string) matches both:
After:
Error: app.bar called with argument types (string) matches multiple overloads after implicit conversions:
Error messages related to operator overloading have been improved. When the related template functions (opUnary, opBinary, opBinaryRight, opOpAssign, opIndex, opSlice) are missing, a suggestion to implement them is given.
When they do exist but fail to instantiate, the error from instantiation is shown. There's no longer a need to manually e.g. rewrite s + 1 to s.opBinary!"+"(1) to diagnose the error.
struct S {} void main() { S s; const x = s[3 .. "4"]; }
Before:
app.d(6): Error: no [] operator overload for type S
After:
app.d(6): Error: no [3.."4"] operator overload for type S app.d(1): perhaps define auto opSlice(int lower, string upper) {} for app.S
struct Str {} struct Number { int x; int opBinary(string op : "+")(int rhs) => this.x + x; } void f(Str str, Number number) { const s = str ~ "hey"; const n = number + "oops"; }
Before:
app.d(12): Error: incompatible types for (str) ~ ("hey"): Str and string const s = str ~ "hey"; ^ app.d(13): Error: incompatible types for (number) + ("oops"): Number and string const n = number + "oops";
After:
app.d(12): Error: operator ~ is not defined for type Str const s = str ~ "hey"; ^ app.d(2): perhaps overload the operator with auto opBinary(string op : "~")(string rhs) {} struct Str {} ^ app.d(13): Error: function test_.Number.opBinary!"+".opBinary(int rhs) is not callable using argument types (string) const n = number + "oops"; ^ app.d(13): cannot pass argument "oops" of type string to parameter int rhs app.d(7): opBinary defined here int opBinary(string op : "+")(int rhs) => this.x + x; ^
Furthermore:
- D1 operator overloading functions (opAdd, opDot) are completely removed and no longer mentioned in error messages specifically.
- Class allocators (auto new() {}) are not only a semantic error, but no longer parse.
- The compiler now accepts -extern-std=c++23
The compiler now accepts c++23 as a supported standard for -extern-std=. Currently this only changes the value of __traits(getTargetInfo, "cppStd").
- Build time profiling has been added to DMD
The -ftime-trace switch that the LDC compiler already has, is now also available in dmd. It can be used to figure out which parts of your code take the longest to compile, so you can optimize your build times.
dmd -ftime-trace app.d
This will output app.o.time-trace.
A different output file can be selected with -ftime-trace-file=trace.json.
The output is in Google Chrome's profiler format, which can be viewed in an interactive viewer like ui.perfetto.dev.
See also the YouTube tutorial Easily Reduce Build Times by Profiling the D Compiler.
- New traits getBitfieldOffset and getBitfieldWidth for built-in bitfields
This completes the introspection capabilities of built-in bitfields. For example:
struct S { int a,b; int :2, c:3; } static assert(__traits(getBitfieldOffset, S.b) == 0); static assert(__traits(getBitfieldOffset, S.c) == 2); static assert(__traits(getBitfieldWidth, S.b) == 32); static assert(__traits(getBitfieldWidth, S.c) == 3);
- Using the compiler flag -i will now properly pick up C source files
Previously, you needed to manually include *.c source files, it now works just like with D files.
- A pragma for ImportC allows to set nothrow, @nogc or pure
The following new pragma for ImportC allows to set default storage classes for function declarations:
#pragma attribute(push, [storage classes...])
The storage classes nothrow, nogc and pure are supported. Unrecognized attributes are ignored. Enabling a default storage class affects all function declarations after the pragma until it is disabled with another pragma. Declarations in includes are also affected. The changed storage classes are pushed on a stack. The last change can be undone with the following pragma. The following example enables @nogc and nothrow for a library:
#pragma attribute(push, nogc, nothrow) #include
#pragma attribute(pop) This can also disable multiple default storage classes at the same time, if they were enabled with a single #pragma attribute(push, ...) directive.
- Mixin templates can now use assignment syntax
Previously, giving a name to a mixed-in mixin template instance required putting the name at the end. Now, it can also go in front of the instantiation using assignment syntax.
mixin MyMixinTemplate!(Args) myName; // old style mixin myName = MyMixinTemplate!(Args); // new style
- Object file extensions .o and .obj are now accepted on all platforms
Accepting .o and .obj file extensions on all platforms makes DMD behave like Clang and other modern compilers. There is no point in discarding *.o or *.obj depending on the current operating system, as both extensions unambiguously denote object file.
- Objective-C selectors are now automatically generated when not specified with @selector.
Additionally, the Objective-C selector generation rules have changed, following these steps:
- Functions marked with @property will generate setXYZ: for the setters.
- For property functions with names starting with is, that prefix will be stripped off in the setter.
- Selector generation now uses the names of the function parameters instead of their D-mangled types.
Selectors may still be specified with the @selector UDA, in which case it takes precedence over the automatically generated selectors.
These new rules apply both for extern and non-extern Objective-C classes and protocols.
extern(Objective-C) extern class NSObject { static NSObject alloc(); // Generates as `alloc` NSObject init(); // Generates as `init` } extern(Objective-C) class Fox : NSObject { bool fluffy; @property bool isFluffy() => fluffy; // `isFluffy` @property void isFluffy(bool value) { fluffy = value; } // `setFluffy:` void yip(int a) @selector("bark:") { // `bark:` // ... } void doSomething(int a, int b, int c) { // `doSomething:b:c:` // ... } }
These changes should not break any existing code because the automatic selector generation was not present before. And automatic selector generation only applies to extern(Objective-C) methods.
- New compiler switch -oq for DMD
The switch gives fully qualified names to object files, preventing name conflicts when using the switch -od while compiling multiple modules with the same name, but inside different packages. The switch already existed in LDC, but is now in dmd as well.
Example:
dmd -c -oq -od=. app.d util/app.d misc/app.d
This will output app.obj, util.app.obj, and misc.app.obj, instead of just app.obj.
The switch -oq also applies to other outputs, such as Ddoc (-D -Dd=.) and .di header generation (-H -Hd=.).
- Added Placement New Expression
Placement new explicitly provides the storage for new expression to initialize with the newly created value, rather than using the GC.
struct S { float d; int i; char c; } void main() @system @nogc { S s; S* p = new (s) S(3.14, 42, 'X'); // place new object into s assert(p.i == 42 && p.c == 'X'); }
- Postfix type qualifier method attributes for -H and -D
The .di interface file generation and Ddoc output will now have type qualifier attributes placed after the parameter list for methods (and constructors). This avoids confusion with the return type.
struct S { const int f(); // before int f() const; // now }
- The folder samples has been removed from DMD installations
Every DMD release has included a folder with small D code examples. These examples are quite old, and not a good representation of modern D. They're also hard to discover, since D compilers are often installed through an installer or package manager.
Since there are better resources available online nowadays, these samples have been moved to the undeaD repository.
- New keyword __rvalue
The newly added primary expression of the form __rvalue(expression) evaluates to expression, except that it is treated as an rvalue, even if would be an lvalue otherwise.
Overloads on ref:
foo( S s); // selected if the argument is an rvalue foo(ref S s); // selected if the argument is an lvalue S s; S bar(); ... foo(s); // selects foo(ref S) foo(bar()); // selects foo(S)
With this change:
foo(__rvalue(s)); // selects foo(S)
This also applies to constructors and assignments, meaning move constructors and move assignments are enabled. Moving instead of copying can be much more resource efficient, as, say, a string can be moved rather than copied/deleted.
A moved object will still be destructed, so take that into account when moving a field - set it to a benign value that can be destructed.
__rvalue may also be used as an attribute on a function which returns by ref to declare that the result should be treated as an rvalue at the callsite:
ref T move(T)(return ref T source) __rvalue { return source; } S s; S t = move(s); // call expression rewritten as: S t = __rvalue(move(s))
This is used as an internal tool to implement library primitives such as move and forward.
- Add -preview=safer switch for safety checking on unattributed functions
All the checks currently enabled in @safe code, that are easily fixed (as in the fix is constrained to the function), will be enabled in -preview=safer code.
Code not easily fixed, such as calls to @system or unattributed functions, will be allowed as before.
void f(); @system void g(); void main() { int* p; p++; // Error, pointer arithmetic f(); // allowed g(); // allowed }
For more information, see this document.
- Shortened method syntax can now be used in constructors
This used to raise an error (cannot return expression from constructor), but is now supported:
struct Number { int x; void vf(int); this(int x) => vf(x); this(float x) => this(cast(int) x); }
The expression body must be a this/super call or have type void.
Postblits and destructors already supported shortened method syntax because they return void.
Runtime changes
- Add Windows BCrypt bindings under core.sys.windows.bcrypt
Adds full BCrypt API bindings to the Windows-specific system bindings.
The Windows-specific bindings under core.sys.windows.sdkddkver and core.sys.windows.w32api have also been updated in order to facilitate the creation of the BCrypt bindings.
- Remove criticalRegionLock
The criticalRegionLock feature suffer from a serious design flaw: https://issues.dlang.org/show_bug.cgi?id=24741
It turns out it is not used, so rather than fixing the flaw, the feature was removed.
- Adds expect, likely, unlikely, and trap to core.builtins
Adds the functions expect and likely/unlikely for branch and value hints for the LDC/GDC compilers. DMD ignores these hints.
Adds the function trap to be lowered to the target-dependent trap instruction. If the target does not have a trap instruction, this intrinsic will be lowered to a call of the abort function.
- New segfault handler showing backtraces for null access / call stack overflow on linux
While buffer overflows are usually caught by array bounds checks, there are still other situations where a segmentation fault occurs in D programs:
- null pointer dereference
- Corrupted or dangling pointer dereference in @system code
- Call stack overflow (infinite recursion)
These result in an uninformative runtime error such as:
[1] 37856 segmentation fault (core dumped) ./app
In order to find the cause of the error, the program needs to be run again in a debugger like GDB.
There is the registerMemoryErrorHandler function in etc.linux.memoryerror, which catches SIGSEGV signals and transforms them into a thrown InvalidPointerError, providing a better message. However, it doesn't work on call stack overflow, because it uses stack memory itself, so the segfault handler segfaults. It also relies on inline assembly, limiting it to the x86 architecture.
A new function registerMemoryAssertHandler has been introduced, which does handle stack overflow by setting up an altstack. It uses assert(0) instead of throwing an Error object, so the result corresponds to the chosen -checkaction setting.
Example:
void main() { version (linux) { import etc.linux.memoryerror; registerMemoryAssertHandler(); } int* p = null; int* q = cast(int*) 0xDEADBEEF; // int a = *p; // segmentation fault: null pointer read/write operation // int b = *q; // segmentation fault: invalid pointer read/write operation recurse(); // segmentation fault: call stack overflow } void recurse() { recurse(); }
Output with dmd -g -run app.d:
core.exception.AssertError@src/etc/linux/memoryerror.d(82): segmentation fault: call stack overflow –––––––––– src/core/exception.d:587 onAssertErrorMsg [0x58e270d2802d] src/core/exception.d:803 _d_assert_msg [0x58e270d1fb64] src/etc/linux/memoryerror.d:82 _d_handleSignalAssert [0x58e270d1f48d] ??:? [0x7004139e876f] ./app.d:16 void scratch.recurse() [0x58e270d1d757] ./app.d:18 void scratch.recurse() [0x58e270d1d75c] ./app.d:18 void scratch.recurse() [0x58e270d1d75c] ./app.d:18 void scratch.recurse() [0x58e270d1d75c] ./app.d:18 void scratch.recurse() [0x58e270d1d75c] ... ... ...
Library changes
- Added std.conv.bitCast
This convenience function allows reinterpreting casts to be written in a more readable way.
uint n = 0xDEADBEEF; // Before writeln("Bytes of n are: ", *cast(const ubyte[4]*) &n); // After writeln("Bytes of n are: ", n.bitCast!(const ubyte[4]));
- Extend the functionality of formattedRead to permit a std.file.slurp like execution.
Template argument types can now be passed to formattedRead along with a format string to parse and read the input range as a Tuple of those arguments. All arguments must be read successfully, otherwise, and unlike std.file.slurp which has non exhaustive option for partial reads, it'll throw a std.format.FormatException.
import std.exception : assertThrown; import std.format : FormatException; import std.typecons : tuple; @safe pure unittest { auto complete = "hello!34.5:124".formattedRead!(string, double, int)("%s!%s:%s"); assert(complete == tuple("hello", 34.5, 124)); assertThrown!FormatException("hello!34.5:".formattedRead!(string, double, int)("%s!%s:%s")); } /// The format string can be checked at compile-time: @safe pure unittest { auto expected = tuple("hello", 124, 34.5); auto result = "hello!124:34.5".formattedRead!("%s!%s:%s", string, int, double); assert(result == expected); assertThrown!FormatException("hello!34.5:".formattedRead!("%s!%s:%s", string, double, int)); }
- Added fromHexString and fromHexStringAsRange functions to std.digest.
This new function enables the converion of a hex string to a range of bytes. Unlike the template std.conv.hexString that was designed to supersede a language feature, this function is usable with runtime input.
The std.conv module lacks facilities to conveniently transform the input to a series of bytes directly. Both std.conv.parse and std.conv.to can only handle the conversion for a single value of the requested target integer type. Furthermore, said functions would allocate a new buffer for the result, while fromHexStringAsRange operates lazily by implementing a forward range.
For further convenience, a validation function std.digest.isHexString was added as well.
- ODBC Bindings in etc.c.odbc have been updated to ODBC 4.0.
ODBC 4.0, via these new bindings, adds the following functionality:
- Support for semi-structured data, such as JSON.
- Collection valued columns.
- Web-based Authorization flows.
A full list of new features can be found here: https://github.com/Microsoft/ODBC-Specification/blob/master/ODBC%204.0.md
Additionally these modules add support for 64-bit ODBC interfaces.
- Added popGrapheme function to std.uni.
The new function is a cross between the existing std.uni.graphemeStride and std.uni.decodeGrapheme functions. The new function both supports @safe pure nothrow @nogc like graphemeStride does as long as you don't rely on autodecoding (side node: @nogc support for graphemeStride added in this release), and works with any non-array ranges just like decodeGrapheme does.
Example:
import std.uni; // Two Union Jacks of the Great Britain in each string s = "\U0001F1EC\U0001F1E7\U0001F1EC\U0001F1E7"; wstring ws = "\U0001F1EC\U0001F1E7\U0001F1EC\U0001F1E7"; dstring ds = "\U0001F1EC\U0001F1E7\U0001F1EC\U0001F1E7"; // String pop length in code units, not points. assert(s.popGrapheme() == 8); assert(ws.popGrapheme() == 4); assert(ds.popGrapheme() == 2); assert(s == "\U0001F1EC\U0001F1E7"); assert(ws == "\U0001F1EC\U0001F1E7"); assert(ds == "\U0001F1EC\U0001F1E7"); import std.algorithm.comparison : equal; import std.algorithm.iteration : filter; // Also works for non-random access ranges as long as the // character type is 32-bit. auto testPiece = "\r\nhello!"d.filter!(x => !x.isAlpha); // Windows-style line ending is two code point in a single grapheme. assert(testPiece.popGrapheme() == 2); assert(testPiece.equal("!"d));
- Added readfln and File.readfln to std.stdio
These functions read a single line of input and parse it using a format string. Unlike readf, they will not accidentally read multiple lines if the user forgets to include a line terminator in the format string—a common mistake for beginners.
- Added the SharedAllocatorList, as the thread-safe version of the regular AllocatorList.
The new std.experimental.allocator.building_blocks.allocator_list.SharedAllocatorList has the same semantics as the regular AllocatorList. Just as the regular AllocatorList, if the BookkeepingAllocator is NullAllocator, the SharedAllocatorList will switch to ouroboros mode, allocationg memory for its own metadata.
SharedAllocatorList!((n) => SharedAscendingPageAllocator(max(n, numPages * pageSize)), NullAllocator) a; auto b = a.allocate(100); assert(b.length == 100); assert(a.deallocate(b));
- New procedural API for std.sumtype
std.sumtype has three new convenience functions for querying and retrieving the value of a SumType object.
- has!T returns true if the SumType object has a value of type T.
- get!T returns the value if its type is T, or asserts if it is not.
- tryGet!T returns the value if its type is T, or throws an exception if it is not.
These functions make it easier to write code using SumType in a procedural style, as opposed to the functional style encouraged by match.
Example:
import std.sumtype; import std.stdio; SumType!(string, double) example = "hello"; if (example.has!string) { writeln("string: ", example.get!string); } else if (example.has!double) { writeln("double: ", example.get!double); } try { writeln("double: ", example.tryGet!double); } catch (MatchException e) { writeln("Couldn't get a double."); }
- std.uni has been upgraded from Unicode 15.1.0 to 16.0.0
This Unicode update was released September 10, 2024, and adds new blocks with characters. See: https://www.unicode.org/versions/Unicode16.0.0/
import std; void main() { const alphaCount = iota(0, dchar.max).filter!(std.uni.isAlpha).walkLength; writeln(alphaCount); // formerly: 138387 // now: 142759 }
List of all bug fixes and enhancements in D 2.112.0:
DMD Compiler regression fixes
- Bugzilla 10440: shared library on osx: worked in 2.062, fails in 2.063 / 2.063.2
- Bugzilla 10577: 2.063 Mixin Regression (works with 2.062)
- Bugzilla 17481: [REG 2.069.0] synchronized: Access Violation with dmd -O on win32
- Bugzilla 21258: Tuple parameters with defaults use the first tuple element for all defaults since 2.094.0-beta.1
- Bugzilla 21414: Spurious "non-constant expression" error with immutable constructors
- Bugzilla 21660: [REG 2.066.0] cannot convert unique immutable(int)** to immutable
- Bugzilla 21740: Typeof mixin regression with v2.096
- Bugzilla 21744: [REG 2.092.0] NRVO sometimes not performed when it should be
- Bugzilla 21813: [REG-master] Bootstrap broken from dmd-cxx baseline.
DMD Compiler bug fixes
- Bugzilla 2: Hook up new dmd command line arguments
- Bugzilla 722: mixin as return value: expression.c:775: virtual void Expression::toMangleBuffer(OutBuffer*): Assertion `0' failed.
- Bugzilla 4184: associative array with certain key types results in corrupt values during iteration
- Bugzilla 4191: [FreeBSD] real constants are rounded to double precision
- Bugzilla 4217: Function overloads are not distinguished when instantiating templates
- Bugzilla 4224: alias this and opDispatch
- Bugzilla 4251: Hole in the const system: immutable(T)[] implicitly casts to ref const(T)[]
- Bugzilla 4267: forward reference error when 2-fold aliasing a template instance
- Bugzilla 9829: rdmd passes '--' to dmd
- Bugzilla 10506: Purity should not be checked in a mixin statement
- Bugzilla 10513: pure overriding method cannot call impure out contract of base class
- Bugzilla 10540: variable used before set for empty static arrays, with -inline -O
- Bugzilla 10742: CTFE of std.digest.digest.digest() crashes DMD.
- Bugzilla 10775: druntime is not set up to handle dynamically loaded shared libraries in linux
- Bugzilla 10785: Interface diamond covariance causes silent breakage
- Bugzilla 10811: Order dependent IFTI failure
- Bugzilla 10840: [CTFE] *this._data.arr is not yet implemented at compile time
- Bugzilla 17462: Order of base interfaces affects compiler behavior
- Bugzilla 17804: Accessing enum' or static' member allocates gc closure
- Bugzilla 18263: selective import with same name masks out this reference in mixin template
- Bugzilla 18614: dmd source uses bool return inconsistently (true should mean success)
- Bugzilla 19788: compiler crash on slicing a enum typed as vector
- Bugzilla 20092: void[1] auto slicing makes the compiler hang
- Bugzilla 20114: -checkaction=context evaluates operand second time on assertion failure
- Bugzilla 20318: Illegal instruction (core dumped)
- Bugzilla 20365: Copy constructor not invoked on static arrays of structs but the postblit works
- Bugzilla 20499: bad error message caused by UFCS attempt on the identifier matching to an import
- Bugzilla 20855: stack overflow when compiling large file
- Bugzilla 20901: static foreach must deep-copy front() per iteration
- Bugzilla 20917: stacking alias this, drops data during assignment
- Bugzilla 21052: buildkite ldc-developers/ldc log file contains not a clue what it is attempting to do
- Bugzilla 21054: Test Suite test/run.d has no documentation on how the dmd under test is specified
- Bugzilla 21126: d_do_test should be built with bootstrap compiler, not compiler being tested
- Bugzilla 21153: DWARF: DMD emits the mangled name for DW_AT_name
- Bugzilla 21179: Test Suite: circleci times out with useless log message
- Bugzilla 21207: Mixin get processed in lexical order, resulting in forward reference issues
- Bugzilla 21225: preview=dtorfields inserts unnecessary dtor call in nothrow ctors
- Bugzilla 21271: C++ header generation ignores extern(D) class methods affecting vtable layout
- Bugzilla 21280: No error output "cast(ubyte[4])("ABCDEF"[0..4]);"
- Bugzilla 21298: Missing error when overriding interface method without in contract with class method with contract
- Bugzilla 21303: Segfault with -preview=dip1021 and -inline on trivial std.socket code
- Bugzilla 21304: dtoh silently ignore default parameters, leading to invalid headers
- Bugzilla 21403: dmd/backend/cgcs.d:375 assert failed
- Bugzilla 21406: CatAssign wrong evaluation/load order at run-time
- Bugzilla 21416: betterC mode program with C++ interface fails to link
- Bugzilla 21476: [codegen] 64 bit C ABI not followed when returning struct with 3 floats
- Bugzilla 21478: Setting a default value to an object field which is a 2D array may cause memory corruption
- Bugzilla 21479: ternary operator returns wrong val with ref return
- Bugzilla 21504: Incorrect eponymous overload called by codegen
- Bugzilla 21549: array ignored in alias declaration
- Bugzilla 21576: __traits(compile) does not automatically infer to empty parameter function template
- Bugzilla 21619: Parameter-less function literal in expression statement fails to parse
- Bugzilla 21646: Speculative recursive reference to struct with semantic error prints "error: unknown"
- Bugzilla 21665: Void initialization should not be allowed for instances of struct with invariant
- Bugzilla 21690: Unable to dynamic cast extern(C++) classes
- Bugzilla 21693: extern(C++) class instance dtors are never called, breaking RAII
- Bugzilla 21745: Closure created in struct constructor passed to class constructor refers to expired stack frame
- Bugzilla 21874: The test suite fails with most recent GDB versions
- Bugzilla 21945: importC AssertError@src/dmd/dsymbolsem.d(4787): Assertion failure
DMD Compiler enhancements
- Bugzilla 10491: Type inference for function arguments with default value
- Bugzilla 10523: Don't call array op functions for short vector ops
- Bugzilla 20075: allow cast(ref T)lvalue for casting lvalues
- Bugzilla 20157: [diagnostic] Name suggest for override should only list virtual functions
- Bugzilla 20334: posix.mak clean target does not remove all generated files
- Bugzilla 21033: enhancement: allow assign to field when the shared owing object has been locked already without cast
- Bugzilla 21098: poor diagnostic when trying to assign a string literal to a char*
- Bugzilla 21142: TypeInfo_Class.offTi() not available via introspection
- Bugzilla 21203: Accept pragma(mangle) on aggregate types
- Bugzilla 21247: AssertArguments should allow for tuple auto expansion
- Bugzilla 21259: struct initialization with deprecated fields should issue deprecation warnings
- Bugzilla 21317: Copy constructor defined but blitting still occurs
- Bugzilla 21562: Allow mixin template declarations without parentheses
- Bugzilla 21605: Instead of giving error on printf format mismatch, correct it
- Bugzilla 21630: assert(0) and assert(false) should not be marked for coverage
- Bugzilla 21718: Preview switches have insufficient descriptions
Phobos regression fixes
- Bugzilla 21435: The windows .win64 make file for phobos depends on the make.exe that is part of the dmd folder.
- Bugzilla 21663: std.concurrency.receiveOnly doesn't work with tuples
- Bugzilla 21757: log2 does not work with reals on CTFE with FreeBSD
- Bugzilla 21774: "formatException is not constant" instead of "static assert error"
Phobos bug fixes
- Bugzilla 4234: Cannot create a std.socket.Socket from an fd
- Bugzilla 4260: windows & basename
- Bugzilla 4305: Take, Chain on top of ranges w/o moveFront()
- Bugzilla 10550: Xorshift32 and Xorshift160 do not generate uniformly-distributed random numbers
- Bugzilla 10796: std.regex: ctRegex bug with '.' and $ in multi-line mode
- Bugzilla 10801: std.regex: support for lookbehind in ctRegex
- Bugzilla 10802: std.regex: ctRegex fails to compile with backreference
- Bugzilla 18950: Std.zip vulnerable to arbitrary file write
- Bugzilla 20301: std.regex.regex doesn't accept a const/immutable array of patterns
- Bugzilla 20502: Converting std.typecons.RefCounted!T to a string gives T's storage location instead of T's fields when T is a struct without an explicit toString
- Bugzilla 20985: std.socket random failures due to environment socket.d(1004)
- Bugzilla 21210: std.traits : isAssignable false positive on disabled copy struct
- Bugzilla 21215: std.range.recurrence leads to an infinite loop
- Bugzilla 21382: std.random.uniform!T(urng) when T is an integer type and urng.front is floating point is broken
- Bugzilla 21384: std.random.uniform!T() and std.random.uniform!T(urng) when T is dchar with any qualifiers can exceed dchar.max
- Bugzilla 21429: Cannot sort large tuple arrays at compile time
- Bugzilla 21452: isCallable erroneously returns false on function templates
- Bugzilla 21456: std.format does not accept enum member with string base type as template parameter
- Bugzilla 21679: Assertion failure in Base64.encoder for empty input range of ranges
Phobos enhancements
- Bugzilla 4266: add support for structs in std.format.doFormat
- Bugzilla 18101: allow Tuple for BetterC
- Bugzilla 19587: std.range.generate's range calls its argument one time too many
- Bugzilla 19983: Add fast path using slice assignment to std.internal.cstring.tempCString
- Bugzilla 20184: String maxsplit
- Bugzilla 21068: Cannot sort a RandomAccessFinite range
- Bugzilla 21267: Make std.complex work with -betterC
- Bugzilla 21397: Nullable doesn't define copy constructors
- Bugzilla 21408: Make std.math.nextUp and nextDown and nextafter work in CTFE for extended-precision real
- Bugzilla 21523: Microsoft Windows std.stdio.File.lock(), tryLock(), unlock(): do not allocate memory for error messages when they are not needed
- Bugzilla 21615: indexOf for arrays
Druntime bug fixes
- Bugzilla 4222: druntime should apply @safe/@system/@trusted
- Bugzilla 9584: Exceptions in D are ludicrously slow (far worse than Java)
- Bugzilla 10701: [GC] segfault in GC
- Bugzilla 18018: Locale not available when linking against snn.lib
Druntime enhancements
- Bugzilla 9585: [AA] Implement getPair() for Associative Arrays
- Bugzilla 21426: dup, idup for arrays plus keys, values for associative arrays: call postblits directly instead of via TypeInfo function pointer
dlang.org bug fixes
- Bugzilla 10731: byLine description incorrect
- Bugzilla 21150: The specification is unclear (static foreach)
- Bugzilla 21189: Plain Old Data and copy constructors
- Bugzilla 21241: html display of changelog does not work in Chrome browser
dlang.org enhancements
- Bugzilla 18127: homepage: Fast code, fast.
- Bugzilla 21105: Casting from a function pointer to a delegate
- Bugzilla 21161: [Variadic Templates] uses outdated example from D1 / Tango
Installer bug fixes
- Bugzilla 20473: Missing file & directory
Contributors to this release (73)
A huge thanks goes to all the awesome people who made this release possible.
- Abhay Pratap
- abul
- Abul Hossain Khan
- Adam Wilson
- Aditya Chincholkar
- Akshat Sharma
- Akshat(DeterminedSage)
- Albert24GG
- Aleksandr Treyger
- Andrei Horodniceanu
- Artha
- Ay1nDas
- Ayan Das
- bangbangsheshotmedown
- Ben Jones
- Brian Callahan
- David Isinta Nyakawa
- Denis Feklushkin
- Dennis
- Dennis Korpel
- drpriver
- Elias Batek
- Emily
- Emmankoko
- Emmanuel Ferdman
- Emmanuel Nyarko
- fossdd
- George-Alex-Berea
- Georgy Markov
- gulugulubing
- H. S. Teoh
- Hiroki Noda
- Iain Buclaw
- Inkrementator
- jmh530
- Jonathan M Davis
- limepoutine
- Manu Evans
- Martin Kinkelin
- Mathias Lang
- Matthew Qiu
- Mike Parker
- Mindy Batek
- Mohamed El Shorbagy
- Nayaab Zameer
- naydef
- Nicholas Wilson
- Nick Treleaven
- papadil
- Parmar Mahipalsinh
- Patrick Schlüter
- Paul Backus
- Per Nordlöw
- Prthmsh7
- Quirin F. Schroll
- Rainer Schuetze
- Richard (Rikki) Andrew Cattermole
- Robert burner Schadek
- Samrendra Pratap Singh
- Sergei Giniatulin
- Sergii K
- Sertonix
- Shivang Shukla
- shivangshukla7020
- Steven Schveighoffer
- Sönke Ludwig
- Teodor Dutu
- Tim Schendekehl
- Timon Gehr
- Tomas Fabrizio Orsi
- Tony Edgin
- Vladimir Panteleev
- Walter Bright