Report a bug
If you spot a problem with this page, click here to create a Bugzilla issue.
Improve this page
Quickly fork, edit online, and submit a pull request for this page. Requires a signed-in GitHub account. This works well for small changes. If you'd like to make larger changes you may want to consider using a local clone.

Change Log: 2.104.0

previous version: 2.103.1

Download D 2.104.0
released Jun 01, 2023

2.104.0 comes with 11 major changes and 63 fixed Bugzilla issues. A huge thanks goes to the 38 contributors who made 2.104.0 possible.

Tools changes

  1. rdmd supports -shared

List of all bug fixes and enhancements in D 2.104.0.

Compiler changes

  1. Better error message when attribute inference fails down the call stack

    When a function fails to infer a function attribute, all callers of that function also fail to infer the attribute. The resulting error message only points to the top most function with the explicit attribute:

    void main() @nogc
    auto fun()
    auto funImpl()
        int[] a = [1, 2, 3];

    app.d(4): Error: @nogc function D main cannot call non-@nogc function

    This doesn't tell the underlying reason why fun wasn't inferred @nogc, and led to use of workarounds to get better information. The new error message will point to the function which failed to infer the attribute:

    app.d(4): Error: @nogc function D main cannot call non-@nogc function
    app.d(7):        which calls app.funImpl
    app.d(14):        which wasn't inferred @nogc because of:
    app.d(14):        array literal in @nogc function app.funImpl may cause a GC allocation

    Note: this was already implemented for @safe since 2.101, but it has now been extended to @nogc, nothrow, and pure.

  2. Using ; as an empty statement has been turned into an error

    This has been deprecated since 2.075.0 because it's error prone:

    void main()
        foreach (i; 0 .. 8);
            // Because of the accidental semicolon above,
            // this block statement is executed once.
            // It's not the loop body

    It will now result in an error.

    app.d(3): Error: use { } for an empty statement, not ;

  3. Using in parameters with non extern(D)/extern(C++) functions is deprecated

    In preparation for enabling -preview=in by default, using in parameters on function that have neither D nor C++ linkage is deprecated. Users can replace instances of in with either const or scope const. Refer to v2.101.0 changelog's for a full rationale.

  4. in ref on parameters has been deprecated in favor of -preview=in

    Using in ref (or ref in) on function parameters will now yield a deprecation. Users are encouraged to remove the ref and compile with -preview=in, which will infer whether the parameter should be passed by reference or value. Users wanting a specific ABI are encouraged to use scope const ref instead. Note that this also applies to auto ref in, which is equivalent to in with -preview=in, but the latter doesn't require the function to be templated.

  5. Throwing qualified objects is now deprecated

    Previously, an immutable, const, inout or shared exception could be thrown and then caught in an unqualified catch (Exception e) clause. That breaks type safety. Throwing a qualified object is now deprecated. This helps to prevent possible mutation of an immutable object in a catch clause.

    The runtime also modifies a thrown object (e.g. to contain a stack trace) which can violate const or immutable objects. Throwing qualified objects has been deprecated for this reason also.

  6. User Defined Attributes now parse Template Arguments

    It was already allowed to put types in UDAs, but the parser would reject basic types written directly, requiring the use of an alias.

    alias Tint = int;
    @Tint void f();

    Also, simple literals that can appear in template instantiations without brackets (example: foo!"arg") require parentheses when used as an attribute:

    @("my test") unittest

    Now, arguments that can appear after a template instantiation foo! can also appear after an @ attribute.

    @int void f();
    @"my test" unittest

Library changes

  1. Better static assert messages for std.algorithm.comparison.clamp

    Until now, clamp used a template constraint to check if the passed types could be used. If they were not, it was very tedious to figure out why.

    As the template constraint is not used for overload resolution the constrains are moved into static asserts with expressive error messages.

  2. std.typecons.Rebindable now supports all types

    Rebindable can now be used to store and rebind values of any type, including immutable struct values.

    To ensure const safety is preserved, the stored values cannot be accessed by reference.

    The implementation used for all previously supported types (classes, interfaces and arrays) is unchanged.

Tools changes

  1. rdmd supports -shared

    rdmd now understands DMD's -shared switch, and sets the default output file name appropriately (.dll, .so, or .dylib depending on the platform), in the same way as -lib.

Dub changes

  1. Add new properties 'cSourcePaths' and 'cImportPaths' to SDL/JSON

    cSourcePaths passes the C source files in all specified directories to the compiler. All C sources found in the given directories for 'cImportPaths' are passed to the D compiler. This ensures backward compatible behaviour for projects that stored C sources aside of D source file, while porting them to D.

    The second keyword 'cImportPaths' will add additional search paths for C headers. These directories are passed to the D compilers as addition include paths. The feature might need additional tweaking, because the include paths are currently joint with the D import paths. This might change in future to support independant search paths for C to be passed to the D compilers.

  2. The way packages are stored internally has changed

    Previous versions of dub stored packages in the following format: $CACHE_PATH/$PACKAGE_NAME-$PACKAGE_VERSION/$PACKAGE_NAME/ Starting from this version, the format will be: $CACHE_PATH/$PACKAGE_NAME/$PACKAGE_VERSION/$PACKAGE_NAME.

    Introducing a new level will help users quickly list what packages they actually have installed, and reduce visibility of packages that might update frequently. It will render various commands (e.g. du) more useful, pave the way for a package GC function, and make manual browsing easier.

    More importantly, it will allow future version of dub to infer the version from the path to the package, removing the need to read (or edit) the recipe file on every dub invocation.

List of all bug fixes and enhancements in D 2.104.0:

DMD Compiler regression fixes

  1. Bugzilla 23764: Message printed twice: Usage of in on parameter
  2. Bugzilla 23832: dmd regression 2.103.0 silent error cannot call decode at runtime
  3. Bugzilla 23874: -profile=gc segfaults / ICE regression
  4. Bugzilla 23882: ICE (segfault) on nasty alias this code
  5. Bugzilla 23905: Initialization of SumType with opaque enum causes ICE
  6. Bugzilla 23913: __traits(getMember) fails for some C symbols

DMD Compiler bug fixes

  1. Bugzilla 12118: Modify immutable data using throw
  2. Bugzilla 18493: [betterC] Can't use aggregated type with postblit
  3. Bugzilla 19454: Name collisions with unnamed function parameters
  4. Bugzilla 19706: Attribute inference in struct fails
  5. Bugzilla 20737: TLS variables unusable with -betterC for Windows MSVC targets
  6. Bugzilla 21667: scope parameter causes 'no size because of forward references'
  7. Bugzilla 22760: Segmentation fault in CppMangleVisitor.template_arg
  8. Bugzilla 22785: joiner does not support range over immutable
  9. Bugzilla 22960: importC: K&R-style functions assume variadic calling convention
  10. Bugzilla 23014: importC: static thread-locals do not work
  11. Bugzilla 23055: importC: using compound-literal array as pointer in CTFE gives 'dereference of invalid pointer'
  12. Bugzilla 23402: importc function definitions from includes can cause D name conflicts
  13. Bugzilla 23427: ImportC: some bitfield combinations lead to wrong size struct
  14. Bugzilla 23509: ImportC: need statement expressions extension for GLibC's assert()
  15. Bugzilla 23691: compilable/test22294.i:16:1: control Z interpreted as end of file
  16. Bugzilla 23715: ImportC: No rejection of _Thread_local variables declared at function scope without 'static' as per C11 6.2.4-5
  17. Bugzilla 23727: ImportC support imaginary real numbers
  18. Bugzilla 23784: ImportC: __ptr32, __ptr64
  19. Bugzilla 23787: ImportC: __unaligned
  20. Bugzilla 23789: ImportC: __declspec(align(n))
  21. Bugzilla 23795: Cannot cast _Complex!double to _Complex!float
  22. Bugzilla 23801: ImportC: enumeration constant does not fit in an int
  23. Bugzilla 23802: ImportC: __volatile__ is yet another alias for volatile
  24. Bugzilla 23808: #include is not working with importc
  25. Bugzilla 23822: Deprecated struct alias ignored completely
  26. Bugzilla 23826: Deprecated type member passed to template doesn't warn
  27. Bugzilla 23836: Two errors printed for typeof(super) in non-static member context
  28. Bugzilla 23837: importc fails to link on windows x86 but successes on x64
  29. Bugzilla 23838: DMD lexer / parser examples might not compile
  30. Bugzilla 23861: Compiler segmentation fault with ref and alias this
  31. Bugzilla 23863: typeof rejects AliasSeq!() as argument
  32. Bugzilla 23866: ImportC: Multiple __declspecs rejected
  33. Bugzilla 23867: ImportC: undefined identifier __builtin_isnan
  34. Bugzilla 23869: ImportC: undefined identifier isfinite
  35. Bugzilla 23873: [ICE] segfault on imported static if ; else auto x
  36. Bugzilla 23885: [CI] C++ interop tests with g++ fail

DMD Compiler enhancements

  1. Bugzilla 13577: More informative error message for refused immutable foreach loop
  2. Bugzilla 17374: Improve inferred attribute error message
  3. Bugzilla 20268: anonymous function parameter mismatch errors don't include parameters
  4. Bugzilla 22559: ImportC: support gnu case ranges
  5. Bugzilla 23401: ImportC: add -cpp=filename switch to select C preprocessor
  6. Bugzilla 23862: with statement should accept an expression with enum type

Phobos bug fixes

  1. Bugzilla 19642: std.range.slide!(No.withPartial) on lengthless forward range: get empty when expecting one window
  2. Bugzilla 22147: DList can't accept a struct with postblit disabled
  3. Bugzilla 22786: maxElement et al does not support range over immutable
  4. Bugzilla 23834: std.file : File links to c functions are invalid and need updating
  5. Bugzilla 23846: std.math can't compile under macos rosetta

Phobos enhancements

  1. Bugzilla 6106: Keep track of changes during replace function
  2. Bugzilla 14478: isInputRange should allow ranges of non-copyable elements
  3. Bugzilla 23769: Lambda isn't a unary predicate for lambda that doesn't compile

Druntime bug fixes

  1. Bugzilla 14891: profilegc_setlogfilename w/o null-terminated string might fail during fopen
  2. Bugzilla 23949: core.stdc.assert_ for FreeBSD and DragonFlyBSD is incorrect

Druntime enhancements

  1. Bugzilla 11989: Phase out TickDuration bug fixes

  1. Bugzilla 14932: The language specification does not define what the shared attribute does
  2. Bugzilla 23698: ImportC: __stdcall is not documented as supported MSVC/DMC extensions
  3. Bugzilla 23699: ImportC: Unclear documentation that struct/union/enum introduce implicit typedefs
  4. Bugzilla 23872: Wrong example in Interfacing to C: Calling printf section

Contributors to this release (38)

A huge thanks goes to all the awesome people who made this release possible.

previous version: 2.103.1