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.105.0

previous version: 2.104.2 – next version: 2.105.1

Download D 2.105.0
released Aug 01, 2023

2.105.0 comes with 12 major changes and 59 fixed Bugzilla issues. A huge thanks goes to the 34 contributors who made 2.105.0 possible.

List of all bug fixes and enhancements in D 2.105.0.

Compiler changes

  1. Assignment-style syntax is now allowed for alias this

    alias this declarations can now be written using the same alias new = old; syntax as other alias declarations.

    struct S
        int n;
        alias this = n;
        // Equivalent to:
        //alias n this;
  2. Catch clause must take only const or mutable exceptions

    In 2.104, throwing qualified types was deprecated.

    It is also unsafe to catch an exception as immutable, inout or shared. This is because the exception may still be accessible through another mutable or non-shared reference. Catching an exception with those qualifiers is now deprecated.

    auto e = new Exception("first");
    try {
            throw e;
    } catch(immutable Exception ie) { // now an error
            e.msg = "second";
            assert(ie.msg == "first"); // would fail
  3. Functions can no longer have enum storage class

    enum on a function declaration had no effect other than being equivalent to the auto storage class when no return type was present. That syntax could be confused with enum manifest constants and is now an error:

    enum void f1() { }  // error
    enum f2() { }       // error

    Instead, remove enum and use auto where necessary:

    void f1() { }
    auto f2() { }
  4. Overloading extern(C) functions is now an error

    Since 2.095.0, defining the same function multiple times in a module is not allowed, since it would result in symbol clashes at link time. Overloading a function with different parameter types is still allowed of course, and works because D mangles symbol names including parameter types. However, some external linkages (such as extern(C), extern(Windows)) don't do this, so overloading them can also result in symbol clashes at link time. Therefore, doing this was deprecated in that release as well.

    This deprecation now turned into an error. As a corrective action, give the function D or C++ linkage, or use a unique function name.

    // Error:
    extern(C) float square(float x) { return x * x; }
    extern(C) double square(double x) { return x * x; }
    // Corrective action:
    extern(C) float squaref(float x) { return x * x; }
    extern(C) double squared(double x) { return x * x; }
    // Or:
    float square(float x) { return x * x; }
    double square(double x) { return x * x; }
  5. Deprecation phase ended for access to private method when overloaded with public method.

    When a private method was overloaded with a public method that came after it, you could access the private overload as if it was public.

    After a deprecation period starting with 2.094, this code is now an error.


    struct Foo
        private void test(int) { }
        public void test(string) { }
  6. Added predefined version identifier VisionOS

    This is Apple's new operating system for their VR/AR device Vision Pro.

  7. Do not error with a C cast when surrounding a type or expression in parentheses when calling or constructing.

    Previous to this version, an expression like (IdentifierOrBasicType)(Expression) would be considered a c-style cast, and disallowed, even if the IdentifierOrBasicType could be used as a callable. This is now allowed, as long as the expression is a call, or a construction.

    struct S { int x; }
    int foo(int x) { return x; }
    auto bar = &foo;
    // these were previously disallowed
    auto s = (S)(5);   // equivalent to S(5)
    auto f = (foo)(5); // equivalent to foo(5)
    auto b = (bar)(5); // equivalent to bar(5)
    auto i = (int)(5); // equivalent to int(5), not a cast.
    // these are not allowed
    auto bad = (int)5; // Error: C style cast illegal, use `cast(int)5`
    auto bad2 = (ubyte)(12345); // Error: cannot implicitly convert expression `12345` of type `int` to `ubyte`

    See Bugzilla 24025: Expressions contained in parentheses should not be assumed to be C casts

Runtime changes

  1. Linux input header translations were added to druntime

    These headers give access to the Linux Input Subsystem userspace API, which is used to read input from e.g. keyboards, touch screens, and game controllers, or to emulate input devices. You can now import them through core.sys.linux:

    import core.sys.linux.input; // linux/input.h
    import core.sys.linux.input_event_codes; // linux/input-event-codes.h
    import core.sys.linux.uinput; // linux/uinput.h
  2. Integration with the Valgrind memcheck tool has been added to the garbage collector

    The garbage collector gained a compile-time option to enable integration with Valgrind's memcheck tool. When it is enabled, the GC will communicate with Valgrind and inform it which memory access operations are valid and which are not.

    The integration allows catching memory errors in D programs which mix safe (GC) and unsafe (manual) memory management, for example:

    import core.memory;
    void main()
        auto arr = new int[3];;
        arr[1] = 42; // use after free

    To use it, obtain the DMD source code, then include the garbage collector and lifetime implementation into your program's compilation and compile with the -debug=VALGRIND option:

    git clone -b v2.105.0 --depth=1
    dmd -g -debug=VALGRIND program.d -Idmd/druntime/src dmd/druntime/src/{core/internal/gc/impl/conservative/gc,rt/lifetime,etc/valgrind/valgrind}.d
    valgrind --tool=memcheck ./program

    The option is compatible with other GC debugging build options, such as MEMSTOMP and SENTINEL.

    Dub users can try the following equivalent recipe:

    git clone -b v2.105.0 --depth=1
    cat >> dub.sdl <<EOF
    debugVersions "VALGRIND"
    sourceFiles "dmd/druntime/src/core/internal/gc/impl/conservative/gc.d"
    sourceFiles "dmd/druntime/src/rt/lifetime.d"
    sourceFiles "dmd/druntime/src/etc/valgrind/valgrind.d"
    importPaths "dmd/druntime/src"
    dub build
    valgrind --tool=memcheck ./program

Library changes

  1. Better static assert messages for std.algorithm.iteration.permutations

    Until now, permutations 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. Added std.system.instructionSetArchitecture and std.system.ISA

    A new enum representing the instruction set architecture for the targeted system was added. It is intended for cases where a targeted CPU's ISA is only needed at runtime, such as providing human-readable messages as demonstrated below.

    import std.stdio;
    import std.system;
    void main()
        writeln("Hello ", instructionSetArchitecture, " world!");

Dub changes

  1. Exposed --d-versions CLI flag

    You can now specify --d-versions=Xyz to basically insert version = Xyz; into all D source files. This is the same as specifying versions in your dub.sdl / dub.json file, but from the CLI and unrelated to any build types or configurations.

List of all bug fixes and enhancements in D 2.105.0:

DMD Compiler regression fixes

  1. Bugzilla 22427: betterC: casting an array causes linker error in string comparison.
  2. Bugzilla 24018: array concatenation doesn't work with disabled default construction

DMD Compiler bug fixes

  1. Bugzilla 7184: parse error on *(x)++
  2. Bugzilla 11612: Inconsistent error on negative new array size
  3. Bugzilla 13063: enum is allowed as storage class for functions
  4. Bugzilla 16384: Invariant not called with multiple defined.
  5. Bugzilla 18528: dmd should deduplicate identical errors
  6. Bugzilla 20008: __traits(allMembers) of packages is complete nonsense
  7. Bugzilla 20687: Allow member function address as const initializer
  8. Bugzilla 21415: catch immutable exceptions breaks immutable
  9. Bugzilla 21425: Using va_start twice results in wrong values
  10. Bugzilla 23719: runnable/test22071.c:22:16: error: ‘abc’ is a pointer; did you mean to use ‘->’?
  11. Bugzilla 23857: backend inliner takes too long on recursive function call
  12. Bugzilla 23870: ImportC doesn't accept '' followed by newline, whereas VC does
  13. Bugzilla 23875: ImportC: __attribute__ in a cast doesn't work
  14. Bugzilla 23879: ImportC: Windows system headers use __alignof
  15. Bugzilla 23880: ImportC: __attribute__((vector_size(N))) is not implemented
  16. Bugzilla 23885: [CI] C++ interop tests with g++ fail
  17. Bugzilla 23900: @safe is allowed in inline asm
  18. Bugzilla 23908: confusing nonexistent import hint on cyclic import
  19. Bugzilla 23912: Destructor disables scope inference
  20. Bugzilla 23914: "auto ref" resolution on return value prevented by noreturn (bottom type)
  21. Bugzilla 23935: ImportC: __pragma not allowed between struct and tag name
  22. Bugzilla 23936: ImportC: pragma pack is not working for structs
  23. Bugzilla 23947: If a class overloads a method mixing private and public and the last overload is public, the method is always public.
  24. Bugzilla 23968: Deprecation not emitted with alias to template function in UFCS
  25. Bugzilla 23988: Conditional Exp does not bring enums to correct common type if one leg is const
  26. Bugzilla 24010: Destructor called before end of scope for tuples
  27. Bugzilla 24017: [UFCS] Bypassing nothrow with debug doesn’t work
  28. Bugzilla 24024: cannot pass class this to ref class
  29. Bugzilla 24025: Expressions contained in parentheses should not be assumed to be C casts
  30. Bugzilla 24029: ImportC: symbol name clash on statement expressions

DMD Compiler enhancements

  1. Bugzilla 4663: Wrong 'static' position error message
  2. Bugzilla 15436: Compiler still refers to AliasSeq-s as "tuple"-s (and TypeTuple?)
  3. Bugzilla 23475: confusing printf deprecation message with ulong/long on Windows
  4. Bugzilla 23871: ImportC: __attribute not recognized
  5. Bugzilla 23877: ImportC: Importing byteswap.h results in undefined reference to core.bitop.byteswap
  6. Bugzilla 23886: ImportC preprocessor directive #ident not supported
  7. Bugzilla 23928: improve error msg: scope variable s assigned to non-scope parameter this calling abc
  8. Bugzilla 23931: Error: reference to local variable this calling non-scope member function this.this()
  9. Bugzilla 23948: __FILE__ and __MODULE__ cannot be implicitly converted to const(char)* as default paramenter
  10. Bugzilla 23971: Provide clearer error message when trying to return a slice with C++ linkage
  11. Bugzilla 24000: show the open bracket "{" location for Error: matching } expected, not End of File
  12. Bugzilla 24023: Unnecessary module prefix in error message types

Phobos bug fixes

  1. Bugzilla 23361: std.uni.normalize should be pure
  2. Bugzilla 23844: chain(only) doesn't support immutable structs
  3. Bugzilla 23940: std.getopt does not assert with options that only differ in case with config.caseInsensitive
  4. Bugzilla 23997: isClose(1, -double.infinity) returns true
  5. Bugzilla 24028: BigInt power operator ignores sign of exponent

Phobos enhancements

  1. Bugzilla 23881: std.system has no function for system architecture
  2. Bugzilla 23922: [std.socket]

Druntime bug fixes

  1. Bugzilla 23312: Crash when calling writeln in WinMain

Druntime enhancements

  1. Bugzilla 23980: OpenBSD: Add getthrname(2) and setthrname(2) to unistd.d
  2. Bugzilla 24044: Support float opCmp(...) with array bug fixes

  1. Bugzilla 23692: ImportC: __pragma and __declspec are not documented as supported Visual C extensions
  2. Bugzilla 23697: No examples of invalid forward references in C code accepted by ImportC
  3. Bugzilla 23946: specifications state that "there can only be one destructor" which can be confusing because of mixin templates enhancements

  1. Bugzilla 5636: Array ops use lexicographic comparison instead of vector-style element-wise
  2. Bugzilla 23571: Discussion of manifest constants in enum documentation is confusing at best

Contributors to this release (34)

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

previous version: 2.104.2 – next version: 2.105.1