Change Log: 2.112.0
Download D 2.112.0 Beta
to be released Jun 01, 2025
Compiler changes
Runtime changes
Library changes
List of all bug fixes and enhancements in D 2.112.0.
Compiler changes
- Keywords auto and ref must be adjacent for auto ref return.
Similar to auto ref parameters in 2.111, it's now deprecated to declare an auto ref return type without putting those two keywords next to each other as well.
ref auto int f() => 3; auto { ref int g() => 3; } // Correction: auto ref f() => 3; auto ref g() => 3;
- 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").
Runtime changes
- core.int128: Add mul and udivmod overloads for 64-bit operands
These map to a single x86_64 instruction and have accordingly been optimized via inline assembly.
import core.int128; ulong a, b; Cent product128 = mul(a, b); ulong divisor64 = …; ulong modulus64; ulong quotient64 = udivmod(product128, divisor64, modulus64);
- Fixed generated binaries crashing on macOS 15.4
macOS 15.4 has introduced an undocumented ABI change to the format of thread local variable section, which causes almost all executable built with previous D compiler versions to crash during initialization, if they use DRuntime. This release introduces a mitigation for this issue that is backwards compatible with previous versions of macOS.
- C Macro translations in druntime have been translated to templates
This prevents linking errors when using -betterC. For example:
import core.sys.posix.stdlib; import core.sys.posix.unistd; extern(C) int main() { int status, pid = vfork(); if (pid == 0) { // ... return 0; } waitpid(pid, &status, 0); if (WIFEXITED(status)) { // ... } return 0; }
This would fail to compile with the -betterC flag:
Error: undefined reference to `core.sys.posix.sys.wait.WIFEXITED(int)` referenced from `main`
The reason is that WIFEXITED is a C macro that was translated to a D function in druntime, which requires linking with druntime to use. Now that it's a template, it will be lazily instantiated and the program compiles.
Library changes
- Add lazyCache to std.algorithm.iteration
The new lazyCache function provides a lazily evaluated range caching mechanism. Unlike cache, which eagerly evaluates range elements during construction, lazyCache defers evaluation until elements are explicitly requested.
auto result = iota(-4, 5).map!(a => tuple(a, expensiveComputation(a)))().lazyCache(); // No computations performed at this point auto firstElement = result.front; // First element is now evaluated
See the std.algorithm.iteration.lazyCache documentation for more details.
- getrandom() backwards compatibility shim
To restore compatibility with older Linux platforms where getrandom() is unavailable either due to an outdated kernel or a legacy C library, Phobos now ships with a shim that emulates a limited subset of getrandom()’s behavior by reading random bytes from /dev/urandom.
To enable the shim, build DMD and Phobos with the environment variable LINUX_LEGACY_EMULATE_GETRANDOM set to 1.
cd phobos LINUX_LEGACY_EMULATE_GETRANDOM=1 make
This functionality is a temporary fix and expected to be removed again soon by an upcoming release (approx. v2.112.0 or v2.113.0). The expected change is to replace the current “binding or shim” solution with a syscall wrapper and automatic /dev/urandom fallback.
- Add an internal multi-backend entropy system
This Phobos release introduces an internal multi-backend system for the retrieval of entropy (as in cryptographically-secure random numbers obtained from a suitable random number generator provided by the operating system).
The current implementation supports the getrandom syscall on Linux.
On BSD systems arc4random_buf or getentropy are used — depending on which is implemented by the OS and powered by a secure (non-RC4) algorithm.
Additionally, reading entropy from the character devices /dev/urandom and /dev/random is available on all POSIX targets.
On Windows BCryptGenRandom (from the Cryptography API: Next Generation (“BCrypt”)) is provided as a backend. CryptGenRandom from the legacy CryptoAPI is not supported for the time being.
Furthermore, this replaces the getrandom backwards compatibility shim that had been added by v2.111.1 for Linux targets. Instead backwards compatibility is now provided by a hunt strategy algorithm that tries potentially available entropy sources one by one to find one that is available on the running system. Given that the character devices serve as a fallback option here, urandom is favored over random. That is because modern kernel versions — where random would exhibit the usually more preferable behavior of blocking only until the entropy pool has been initialized — will also provide the getrandom syscall in the first place. Performing the syscall, in turn, is even better as it does not depend on the runtime environment exposing the special devices in predefined locations, thus working also within chroot environments.
- Add writeText, writeWText, and writeDText to std.conv
These functions are variants of the existing text, wtext, and dtext functions. Instead of returning a string, they write their output to an output range.
Like text, writeText can accept an interpolated expression sequence as an argument.
Example:
import std.conv : writeText; import std.array : appender; auto output = appender!string(); output.writeText(i"2 + 2 == $(2 + 2)"); assert(output.data == "2 + 2 == 4");
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
DMD Compiler bug fixes
- Bugzilla 2: Hook up new dmd command line arguments
- 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 9829: rdmd passes '--' to dmd
- 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 18263: selective import with same name masks out this reference in mixin template
- Bugzilla 20318: Illegal instruction (core dumped)
- 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 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 21304: dtoh silently ignore default parameters, leading to invalid headers
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 20334: posix.mak clean target does not remove all generated files
- Bugzilla 21098: poor diagnostic when trying to assign a string literal to a char*
- 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
Phobos bug fixes
- Bugzilla 10550: Xorshift32 and Xorshift160 do not generate uniformly-distributed random numbers
- 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 21210: std.traits : isAssignable false positive on disabled copy struct
- Bugzilla 21215: std.range.recurrence leads to an infinite loop
Phobos enhancements
- Bugzilla 21068: Cannot sort a RandomAccessFinite range
- Bugzilla 21267: Make std.complex work with -betterC
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
Druntime enhancements
- Bugzilla 9585: [AA] Implement getPair() for Associative Arrays
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
Contributors to this release (44)
A huge thanks goes to all the awesome people who made this release possible.
- Abhay Pratap
- abul
- Abul Hossain Khan
- Aditya Chincholkar
- Akshat Sharma
- Akshat(DeterminedSage)
- Albert24GG
- Aleksandr Treyger
- Artha
- Ay1nDas
- Ayan Das
- bangbangsheshotmedown
- David Isinta Nyakawa
- Denis Feklushkin
- Dennis
- Dennis Korpel
- drpriver
- Elias Batek
- Emily
- fossdd
- gulugulubing
- Iain Buclaw
- Inkrementator
- Jonathan M Davis
- Manu Evans
- Martin Kinkelin
- Matthew Qiu
- Nayaab Zameer
- Nicholas Wilson
- Nick Treleaven
- Parmar Mahipalsinh
- Patrick Schlüter
- Paul Backus
- Prthmsh7
- Quirin F. Schroll
- Rainer Schuetze
- Richard (Rikki) Andrew Cattermole
- Samrendra Pratap Singh
- Shivang Shukla
- shivangshukla7020
- Sönke Ludwig
- Tomas Fabrizio Orsi
- Vladimir Panteleev
- Walter Bright