Change Log: 2.107.0
Download D 2.107.0
released Feb 01, 2024
Compiler changes
Runtime changes
Library changes
List of all bug fixes and enhancements in D 2.107.0.
Compiler changes
- A string literal as an assert condition is deprecated
Boolean evaluation of a string literal could happen unintentionally e.g. when an assert(0, "message") was meant and the 0 was missing.
assert("unexpected runtime condition"); static assert("unhandled case for `", T, "`");
The 2 asserts would silently always have no effect. Now these cases will be detected with deprecation messages. If the original behaviour was actually intended, use expr !is null instead:
assert("" !is null); static assert("" !is null);
- Makefiles cleanup for the compiler
The Makefiles for building the compiler (compiler/src/{posix,win32,win64}.mak) have been deprecated for a while, and finally removed. Please use the compiler/src/build.d tool directly now (see docs), or build compiler and druntime in one step via the top-level Makefile in the repo root, e.g., for an optimized build using an LDC host compiler: make -jN HOST_DMD=ldmd2 ENABLE_RELEASE=1 ENABLE_LTO=1
The top-level Makefile has been renamed from posix.mak to Makefile (with a deprecated posix.mak forwarder). The semantics of some targets have slightly changed, e.g., druntime is included in the test, install and clean targets now.
The legacy src/posix.mak file still exists, but forwards to the top-level Makefile. So e.g. the default all target now includes druntime too, not just the compiler.
Top-level win{32,64}.mak and legacy src/win{32,64}.mak files (for DigitalMars make) have been removed altogether. The generic top-level Makefile works on Windows too - with a GNU make (and a git installation providing bash and GNU tools).
Long-deprecated compiler/test/Makefile has also been removed; use compiler/test/run.d directly instead (see docs).
- Unrecognized pragmas are no longer an error, but instead simply ignored
Previously, unrecognized pragmas would issue a hard error unless you used the -ignore dmd switch. Now, they are always ignored and the -ignore dmd switch is ignored.
- Added @standalone for module constructors
When two modules import each other and both have module constructors, druntime would throw an error because it can't determine which to run first.
This could be circumvented by using pragma(crt_constructor) instead, but in C runtime constructors, druntime isn't initialized. Therefore the Garbage Collector can't be used in such constructors.
@standalone is a new attribute that can be used to mark module constructors that run after druntime has been initialized, but do not depend on any other module constructors being run before it, so it will not cause a cyclic dependency error. It must be imported from core.attribute.
The compiler doesn't verify that the module constructor truly doesn't depend on other variables being initialized, so it must be enforced manually. Because of this, they must be marked @system or @trusted.
import core.attribute : standalone; immutable int* x; @standalone @system shared static this() { x = new int(10); } void main() { assert(*x == 10); }
If possible, prefer to solve cyclic dependency errors by putting the offending module constructors into their own smaller modules instead of using @standalone.
- _d_newarray{mTX,miTX,OpT} are converted to a single template: _d_newarraymTX
The template _d_newarraymTX now uses DBI to check what type of initialiser is required by the type of the elements in the array. Thus it replaces both _d_newarraymTX and _d_newarraymiTX.
_d_newarrayOpT was the generic implementation of both of the above hooks. It first allocated the "outer" arrays as pointer arrays and then it called either _d_newarrayT or _d_newarrayiT, to allocate initialise the "inner" 1-dimensional arrays accordingly. Now this is no longer needed due to the merge between _d_newarraymTX and _d_newarraymiTX.
Now the compiler performs the following lowering:
S[][] s = new S[][](2, 3) // is now lowered to: S[] s = _d_newarraymTX!(S[][], S)([2, 3]);
This change adds the new template to core.internal.array.construction.
Runtime changes
- Using an invalid MemoryOrder for core.atomic operations are now rejected at compile time
The following core.atomic functions have become more restrictive:
- atomicLoad and atomicStore now reject being instantiated with the
In most cases, code that previously used MemoryOrder.acq_rel should switch to use MemoryOrder.seq instead.
// Error: atomicLoad!(MemoryOrder.acq_rel)(src); atomicStore!(MemoryOrder.acq_rel)(dest, value); // Corrective action: atomicLoad!(MemoryOrder.seq)(src); atomicStore!(MemoryOrder.seq)(dest, value); // Or: atomicLoad(src); atomicStore(dest, value);
- atomicExchange now rejects being instantiated with the argument
In most cases, code that previously used MemoryOrder.acq should switch to use MemoryOrder.seq instead.
// Error: atomicExchange!(MemoryOrder.acq)(dest, value); // Corrective action: atomicExchange!(MemoryOrder.seq)(dest, value); // Or: atomicExchange(dest, value);
- atomicCompareExchangeWeak and atomicCompareExchangeStrong now reject
In most cases, code that previously used either of these should switch to use MemoryOrder.raw instead.
// Error: atomicExchangeWeak!(MemoryOrder.rel, MemoryOrder.rel)(dest, compare, value); atomicExchangeWeakNoResult!(MemoryOrder.acq_rel, MemoryOrder.acq_rel)(dest, compare, value); atomicExchangeStrong!(MemoryOrder.acq, MemoryOrder.rel)(dest, compare, value); atomicExchangeStrongNoResult!(MemoryOrder.seq, MemoryOrder.acq_rel)(dest, compare, value); // Corrective action: atomicExchangeWeak!(MemoryOrder.rel, MemoryOrder.raw)(dest, compare, value); atomicExchangeWeakNoResult!(MemoryOrder.acq_rel, MemoryOrder.raw)(dest, compare, value); atomicExchangeStrong!(MemoryOrder.acq, MemoryOrder.raw)(dest, compare, value); atomicExchangeStrongNoResult!(MemoryOrder.seq, MemoryOrder.raw)(dest, compare, value);
- atomicCompareExchangeWeak and atomicCompareExchangeStrong additionally
In most cases, code that violates this contract should use the same MemoryOrder for both succ and fail arguments.
// Error: atomicExchangeWeak!(MemoryOrder.raw)(dest, compare, value); atomicExchangeStrong!(MemoryOrder.acq, MemoryOrder.seq)(dest, compare, value); // Corrective action: atomicExchangeWeak!(MemoryOrder.raw, MemoryOrder.raw)(dest, compare, value); atomicExchangeStrong!(MemoryOrder.acq, MemoryOrder.acq)(dest, compare, value);
- Makefiles cleanup for druntime
The {posix,win32,win64}.mak Makefiles have been merged to a generic Makefile (including the ones in druntime/test/). posix.mak is kept as a deprecated forwarder for now.
On Windows, you can/need to use the generic Makefile too - with a GNU make (and a git installation providing bash and GNU tools). Windows devs can finally exploit parallelism via -j! You may download a prebuilt zipped .exe from https://github.com/dlang/dmd/releases/download/nightly/gnumake-4.4-win64.zip.
- New addition of the C stdatomic header implemented in D
The goal of this module is to assist in porting efforts for code from C to D and to give as close as possible same code generation as the system C compiler counterpart.
If you do not care about code generation quality should the aliases to the function names not exist, you may append _impl to get at the implementation.
If the code generation provided by a given function is not on-par to the system C compiler and it matters to your use case, please report it as a bug.
Library changes
- isForwardRange now takes an optional element type.
isForwardRange now has an optional 2nd template parameter that defaults to void. If not void, it only evaluates to true if the range's element type is the same type as this extra argument, modulo const. For instance, isForwardRange!(int[], const(int)) is true, but isForwardRange!(int[], string) is false.
- Makefiles cleanup
The {posix,win32,win64}.mak Makefiles have been merged to a generic Makefile. posix.mak is kept as a deprecated forwarder for now.
On Windows, you can/need to use the generic Makefile too - with a GNU make (and a git installation providing bash and GNU tools). Windows devs can finally exploit parallelism via -j! You may download a prebuilt zipped .exe from https://github.com/dlang/dmd/releases/download/nightly/gnumake-4.4-win64.zip.
List of all bug fixes and enhancements in D 2.107.0:
DMD Compiler regression fixes
- Bugzilla 24266: ImportC: struct initializer entry gets ignored
- Bugzilla 24274: [REG master] ImportC: unrecognized C initializer with array in struct
- Bugzilla 24295: [betterC] ICE with new int[]
- Bugzilla 24301: [REG 2.100] Misleading error message when passing non-copyable struct by value in @safe code
- Bugzilla 24338: Cannot concatenate dynamic arrays of enum type with static array base type
DMD Compiler bug fixes
- Bugzilla 16357: cast(T[])[x] casts x to T instead of [x] to T[]
- Bugzilla 20339: isPOD returns true if sizeof is accessed inside struct declaration
- Bugzilla 20369: shadowed variable in foreach loop always considered "foreach variable"
- Bugzilla 22216: Incomplete/incorrect error message for mutability overloads
- Bugzilla 22905: gdb backtrace contains wrong location
- Bugzilla 23411: ImportC: undefined identifier __builtin_nanf
- Bugzilla 23713: compilable/testcstuff1.c:206:1: error: static assertion failed: sizeof(u'a') == 4
- Bugzilla 23714: compilable/testcstuff1.c:213:1: error: static assertion failed: u'ab' == 0x610062
- Bugzilla 23972: class identity check is broken
- Bugzilla 24031: ImportC: rejects nested C initializers
- Bugzilla 24094: importC __declspec not working in front of declaration statement
- Bugzilla 24200: ImportC: .di file collected macro conflicts with Special Token
- Bugzilla 24224: __traits(initSymbol) treats aggregate-derived enum as base type
- Bugzilla 24248: const constructor call with mutable target gives wrong error message
- Bugzilla 24252: ci: Error: error writing file 'compilable\testcstuff3_0.obj'
- Bugzilla 24264: ImportC: inliner trips on _Bool return
- Bugzilla 24276: ImportC: typedef aliases not emitted correctly in .di files
- Bugzilla 24280: ImportC: forward reference error when compiling multiple files
- Bugzilla 24281: Segfault with missing field after named argument
- Bugzilla 24283: [SIMD][CODEGEN] Bad codegen with and not + AVX2 registers
- Bugzilla 24292: Struct with destructor wrongly returned in register
- Bugzilla 24303: anonymous struct problems when typedef'd in separate C files
- Bugzilla 24304: __uint16_t, __uint32_t, __uint64_t are not recognized
- Bugzilla 24306: ImportC: same name structs in separate C files interfere when compiled together
- Bugzilla 24309: Memory allocation failed on Azure pipeline
- Bugzilla 24311: Named enum with AA base type causes ICE
- Bugzilla 24319: OpenBSD: Use correct type for file_time
- Bugzilla 24326: ImportC: segfault on nameless enum translation with -H
- Bugzilla 24340: Invalid export directives generated
DMD Compiler enhancements
- Bugzilla 14387: Disallow string literals as assert conditions
- Bugzilla 23629: importC: Need to support code coverage analysis
- Bugzilla 24069: ImportC does not parse function pointer as parameter without name
- Bugzilla 24125: ImportC: vector type initializer not understood
- Bugzilla 24155: ImportC: accept C23 default initializers
- Bugzilla 24206: Can't alias a function type that returns a type with a TypeSuffix
- Bugzilla 24238: Confusing "not an lvalue"error messages
- Bugzilla 24247: Improve constructor not callable using $modifier object error
- Bugzilla 24294: ImportC: unrecognized command line option -Wno-builtin-macro-redefined with gcc
- Bugzilla 24297: ImportC incompatible with glibc _FORTIFY_SOURCE
Phobos regression fixes
- Bugzilla 24243: Can't format chain(filter, filter)
Phobos bug fixes
- Bugzilla 24151: std.container.array: Array!string("") does not compile
- Bugzilla 24215: std.traits.isBasicType!Enum should be false
- Bugzilla 24278: std.math.abs promotes unsigned argument to 32 bits
- Bugzilla 24342: T[][].until(T[]) breaks if sentinel is longer than 1.
Phobos enhancements
- Bugzilla 11111: std.algorithm.canFind should support Needles...
- Bugzilla 24075: Can't use toChars with ushort or ubyte
Druntime bug fixes
- Bugzilla 4071: Missing support to share memory and objects between DLLs and executable
- Bugzilla 24272: operations.arrayOp is forced @nogc nothrow pure
- Bugzilla 24298: cpp_delete should check for null
Druntime enhancements
- Bugzilla 20332: associative array clear function should be @safe
dlang.org bug fixes
- Bugzilla 23712: ImportC: Unclear documentation of what type is inferred from integer literals (type of 9223372036854775808 is undefined)
- Bugzilla 24239: dlang.org tests on CircleCI run out of memory
- Bugzilla 24241: Spec disallows missing default arguments
dlang.org enhancements
- Bugzilla 24176: Parameters of opApply delegate don't have to be ref
- Bugzilla 24177: Array literal can implicitly convert to an expected type
- Bugzilla 24210: Function types are not documented
Contributors to this release (37)
A huge thanks goes to all the awesome people who made this release possible.
- Adam D. Ruppe
- Atila Neves
- Basile Burg
- Brian Callahan
- Daniel Pflager
- Danil Sidoruk
- Denis Feklushkin
- Dennis
- Dennis Korpel
- Feldwor
- HuskyNator
- Iain Buclaw
- IchorDev
- Imperatorn
- imrying
- Jeremy
- jibal
- Martin Kinkelin
- Mathias Lang
- Mathis Beer
- mhh
- Mike Parker
- Nicholas Wilson
- Nick Treleaven
- Paul Backus
- Petar Kirov
- Rainer Schuetze
- Razvan Nitu
- richard (rikki) andrew cattermole
- ryuukk
- Sönke Ludwig
- Teodor Dutu
- Tim Schendekehl
- Timon Gehr
- Walter Bright
- Yang Yujie
- Семён Марьясин