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

previous version: 2.097.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


2.098.0 comes with 31 major changes and 181 fixed Bugzilla issues. A huge thanks goes to the 62 contributors who made 2.098.0 possible.

List of all upcoming bug fixes and enhancements in D 2.098.0.

Compiler changes

  1. Deprecation period for ambiguous ternary expressions has ended

    In D, the ternary operator (?:) has a higher precedence than the assignment operator (=), hence:

    true ? stt = "AA" : stt = "BB"
    

    actually means:

    (true ? (stt = "AA") : stt) = "BB",
    

    This is in line with C, and many other languages (except C++), but comes at a surprise to many, which is why this specific combination of ternary and assignment was deprecated in v2.082.0 (2018-09-01).

    The deprecation instructs the user to use parenthesis to make the intent explicit, so the above snippet should read as:

    true ? (stt = "AA") : (stt = "BB")
    

    This deprecation period has now ended and the compiler will now issue an error for ambiguous code.

  2. Usage of the body keyword has been deprecated

    Using body to indicate the body of a function or method in the presence of contracts is now deprecated. Any leftover usage of body can be replaced with do. This replacement, introduced by DIP1003, has been available since DMD v2.075.0 (July 2017).

  3. Deprecate a case of using fully-qualified names to bypass imports

    Since v2.084 it is no longer possible to bypass private imports by using fully-qualified names, this was deprecated in v2.071 but when fully-qualified names are used as a type (vs an expression) the code is accepted without any warning.

    Starting with this release the compiler will now properly deprecate the previous omitted case.

    The issue is best described in the following example:

    import std.algorithm;
    
    // deprecated in v2.071, error since v2.084
    auto a = std.range.Take!(int[]); // Error: undefined identifier `range` in package `std`...
    
    // now it's deprecated, will be error from v2.106
    std.range.Take!(int[]) s;
    
    
  4. Explicit package visibility attribute is now always applied to new scopes

    If a less restrictive package attribute appeared within the scope of another package attribute, the more restrictive parent would override any explicit child visibility.

    Example:

    module pkg.foo;
    
    package(pkg.foo):           // analogous to "private" or plain "package"
    
    package(pkg) int bar();     // package(pkg) was being ignored
    

    Starting from this version, the package visibility attribute is now always applied as long as it is valid. In the given example, this allows any module in the package pkg to import and use the symbol bar.

  5. pragma(mangle) can now be applied to aggregates

    The syntax is pragma(mangle, str_or_decl [, str] ) declaration; where str_or_decl is either: a string expression to substitute the name of declaration; or a class, struct, or union declaration or template instance to use instead of declarations for mangling. If the optional second argument is present, use that as a name instead but keep the namespaces and template parameters of str_or_decl (if any).

    This enables binding with functions that take classes by value or reference and to classes that are D keywords.

    To bind C++'s std::function by value:

    extern(C++, "std")
    {
        template std_function(F)
        {
            pragma(mangle, "function")
            class std_function
            {
                // member variables and functions
            }
        }
    }
    
    template ScopeClass(C , string name)
    {
        enum ns = __traits(getCppNamespaces,C);
        extern(C++, class) extern(C++,(ns))
        {
            pragma(mangle, C, name)
            struct ScopeClass
            {
                char[__traits(classInstanceSize, C)] buffer;
                // member variables and functions
            }
        }
    }
    
    alias FuncType = void function(int);
    alias RawFuncType = typeof(*FuncType.init);
    // Mangles as `void funk(std::function<void(int)> a)`
    extern(C++) void funk( ScopeClass!(std_function!(RawFuncType)),"function") a );
    
  6. Complex and imaginary types are now deprecated

    D previously supported complex and imaginary versions of all floating point types as part of the language.

    float a = 2;
    ifloat b = 4i;
    cfloat c = a + b;
    assert(c == 2 + 4i);
    

    However these types are too specialized to be a part of the core language, and the same functionalities can be implemented as part of a library type. As such, older versions of DMD provided the -transition=complex switch to warn when those builtin types were used. This transition phase has finished, and those deprecations are now turned on by default.

    Users should use std.complex.Complex instead.

    import std.complex;
    float a = 2;
    float b = 4;
    auto c = complex(a, b);
    assert(c == complex(2, 4));
    

    The -transition=complex switch that previously turn on deprecation warnings no longer has an effect and has also been deprecated.

  7. while (auto n = expression) is now supported

    Up until this release, while (auto n = expression) was not supported, although the if counterpart: if (auto n = expression) compiled succesfully. Starting with the current compiler version, while (auto n = expression) is accepted, having the exact same semantics as:

    while (true)
    {
        if (auto n = expression)
        { /* loop body */ }
        else
        { break; }
    }
    

Library changes

  1. Centering formatted output.

    A new flag '=' has been added to the format specifier, which allows to center the output:

    assert(format!"|%=8d|"(1234) == "|  1234  |");
    

    In case the output cannot be centered exactly it is moved slightly to the left if '-' flag is present too and to the right else:

    assert(format!"|%=-8d|"(123) == "|  123   |");
    assert(format!"|%=8d|"(123) == "|   123  |");
    
  2. AllImplicitConversionTargets replaces ImplicitConversionTargets

    The function ImplicitConversionTargets in module std.traits has a design flaw: The list of conversion targets contains some, but not all unsafe conversion targets. To overcome this, a new function AllImplicitConversionTargets has been added and ImplicitConversionTargets has been deprecated.

  3. Formatting integers with %e, %f, %g and %a is now possible.

    The formatting posibilities of integers have been expanded to the specifiers that are typical for floating point numbers: Integers can now be formatted using %e, %f, %g and %a. The result is similar to the result expected for the corresponding floating point value.

    assert(format!"%.3e"(ulong.max) == "1.845e+19");
    assert(format!"%.3,3f"(ulong.max) == "18,446,744,073,709,551,615.000");
    assert(format!"%.3g"(ulong.max) == "1.84e+19");
    assert(format!"%.3a"(ulong.max) == "0x1.000p+64");
    
  4. Implementation of pow(f, -2) and f ^^ -2 changed

    We noticed that the implementation of pow(f, -2) and f ^^ -2 with f being a floating point value, was buggy for some values of f. Unfortunately the fix implies small changes for other values for f (with exponent -2) too: The least significant bits of the result might differ from the current implementation. (This is due to the peculiarities of floating point numbers and cannot be avoided with reasonable means.)

    To avoid problems, make sure, that your algorithms do not rely on the least significant bits of floating point calculations, for example by using isClose instead of ==.

  5. Deprecate std.format : enforceValidFormatSpec

    enforceValidFormatSpec from std.format has been accidentally made public and will be removed from public view in 2.107.0.

  6. Deprecate std.format : formatElement

    formatElement from std.format has been accidentally made public and will be removed from public view in 2.107.0.

    Please use instead of formatElement(sink, value, fmt):

    import std.range : only;
    
    sink.put(format!("%("~fmt~"%)")(only(value)));
    
  7. Deprecate std.format : unformatElement

    unformatElement from std.format has been accidentally made public and will be removed from public view in 2.107.0.

    Please use instead for strings and characters parseElement from std.conv and for all else unformatValue from std.format.read.

  8. FieldnameTuple now returns an empty tuple for interfaces

    Previously FieldNameTuple returned AliasSeq!"" for interfaces as done for non-aggregate types like int, char*, ... . This behaviour was surprising because an instance of that interface may have members that just are not known at compile time.

    FieldNameTuple will now return an empty AliasSeq!() for interfaces.

  9. Fields (formerly FieldTypeTuple) now returns an empty tuple for interfaces

    Previously Fields returned AliasSeq!(Interface) for interfaces as done for non-aggregate types like int, char*, ... . This behaviour was surprising because an instance of an interface may have members that just are not known at compile time.

    Fields will now return an empty AliasSeq!() for interfaces.

  10. Floating point numbers can be formatted at compile time

    Example:

    import std.format : format;
    import std.math : sqrt;
    
    enum pi = format!"%s"(3.1415926f);
    static assert(pi == "3.14159");
    
    enum golden_ratio = format!"|%+-20.10E|"((1 + sqrt(5.0)) / 2);
    static assert(golden_ratio == "|+1.6180339887E+00   |");
    
  11. Formatting floating point numbers don't allocate with the GC anymore.

    The implementation of formatting floating point numbers has been reworked. We made sure that working examples never allocate with the GC, however, we are still using exceptions which are GC managed. Therefore, code that uses formatting correctly will never allocate, but in the case of exceptions, the GC will be used to allocate the exception. We are working on DIP 1008 to solve this issue.

  12. Some reals will be downcast to double when used with std.format.

    In the internals of std.format we replaced a call to snprintf of libc with routines written in D for formatting floating point values. These functions only work for floats, doubles, 64-bit-reals and 80-bit-reals (x87-reals) yet.

    All other reals are handled by downcasting them to doubles before being formatted. This might result in a loss of precision in the output. Further, numbers larger than double.max will be formatted like double.max and numbers large than zero but smaller than the smallest positive double will be formatted like the smallest positive double. Likewise for negative values.

  13. std.typecons.Nullable: Remove deprecated alias get this.

    Nullable no longer implicitly converts to its member. This feature was problematic because a simple use of a value could invisibly cause an assertion due to type conversion. To restore the previous behavior, replace uses of a Nullable value n with n.get.

  14. Documentation of std.format has been completely reworked.

    In the last years, the documentation of std.format was outdated little by little and therefore needed a complete rework. The whole package was reviewed and all documentations, including examples, improved and extended.

    Some highlights:

    • The grammar of the format string was updated.
    • A detailed description of format specifiers was provided.
    • Several examples on how to use the functions and the format strings were added.

  15. Module std.format has been split into smaller modules

    The module std.format has been split into submodules:

    • std.format.spec: Symbols concerning the format string, mainly the struct FormatSpec and the template singleSpec
    • std.format.read: Symbols concerning reading input, mainly the template formattedRead and the template unformatValue
    • std.format.write: Symbols concerning writing output, mainly the template formattedWrite and the template formatValue

    All public symbols are still accessible using std.format as usual.

  16. Module std.math has been split into smaller modules

    The module std.math has been split into submodules:

    • std.math.constants: Mathematical constants, like PI.
    • std.math.algebraic: Basic algebraic functions, like abs and sqrt.
    • std.math.trigonometry: Trigonometric functions, like sin and cos.
    • std.math.rounding: Functions concerned about rounding, like ceil and floor.
    • std.math.exponential: Exponential and logarithmic functions, like pow, exp and log.
    • std.math.remainder: Function calculating the remainder, like fmod.
    • std.math.operations: Floating-point operations, like isClose, nextUp and fmin.
    • std.math.traits: Floating-point introspection, like isNaN and isSubnormal.
    • std.math.hardware: Hardware control: IeeeFlags and FloatingPointControl.

    All public symbols are still accessible using std.math as usual.

  17. splitWhen added to std.algorithm.iteration

    std.algortihm.iteration.splitWhen is a variant of the existing std.algortihm.iteration.chunkBy function that does not require its predicate to be an equivalence relation, allowing it to be used in ways that chunkBy cannot. For example:

    // Grouping by maximum adjacent difference:
    import std.math : abs;
    import std.algorithm;
    auto r3 = [1, 3, 2, 5, 4, 9, 10].splitWhen!((a, b) => abs(a-b) >= 3);
    assert(r3.equal!equal([
        [1, 3, 2],
        [5, 4],
        [9, 10]
    ]));
    

    This would have an undefined result with chunkBy, because it requires that if pred(a,b) and pred(b,c) return true, pred(a,c) must also return true.

  18. The old benchmarking functionality in std.datetime has been removed.

    It had been deprecated in 2.077.0 in favor of std.datetime.stopwatch, which uses core.time.MonoTime and core.time.Duration.

  19. std.exception.enforceEx has been removed.

    It had been deprecated in 2.079 in favor of std.exception.enforce.

  20. New module: std.sumtype

    The sumtype package from code.dlang.org has been added to the standard library as std.sumtype.

    It provides SumType, a generic discriminated union implementation that uses design-by-introspection to generate safe and efficient code, and is intended to serve as a replacement for the legacy std.variant.Algebraic.

    Features of SumType include:

    • Pattern matching.
    • Support for self-referential types.
    • Full compatibility with pure, @safe, @nogc, nothrow, and scope.
    • No dependency on runtime type information (TypeInfo).
    • Compatibility with BetterC.

    Example usage:

    import std.sumtype;
    import std.math : isClose;
    
    struct Fahrenheit { double degrees; }
    struct Celsius { double degrees; }
    struct Kelvin { double degrees; }
    
    alias Temperature = SumType!(Fahrenheit, Celsius, Kelvin);
    
    // Construct from any of the member types.
    Temperature t1 = Fahrenheit(98.6);
    Temperature t2 = Celsius(100);
    Temperature t3 = Kelvin(273);
    
    // Use pattern matching to access the value.
    Fahrenheit toFahrenheit(Temperature t)
    {
        return Fahrenheit(
            t.match!(
                (Fahrenheit f) => f.degrees,
                (Celsius c) => c.degrees * 9.0/5 + 32,
                (Kelvin k) => k.degrees * 9.0/5 - 459.4
            )
        );
    }
    
    assert(toFahrenheit(t1).degrees.isClose(98.6));
    assert(toFahrenheit(t2).degrees.isClose(212));
    assert(toFahrenheit(t3).degrees.isClose(32));
    
    // Use ref to modify the value in place.
    void freeze(ref Temperature t)
    {
        t.match!(
            (ref Fahrenheit f) => f.degrees = 32,
            (ref Celsius c) => c.degrees = 0,
            (ref Kelvin k) => k.degrees = 273
        );
    }
    
    freeze(t1);
    assert(toFahrenheit(t1).degrees.isClose(32));
    
    // Use a catch-all handler to give a default result.
    bool isFahrenheit(Temperature t)
    {
        return t.match!(
            (Fahrenheit f) => true,
            _ => false
        );
    }
    
    assert(isFahrenheit(t1));
    assert(!isFahrenheit(t2));
    assert(!isFahrenheit(t3));
    
  21. std.range.Transposed: Remove deprecated member save

    Transposed never worked as forward range.

Dub changes

  1. Builds dynamicLibrary targets as dynamic libraries instead of static libraries.

    Dub will no longer build dynamicLibrary targetType's as staticLibrary.

    Except for x86_omf. This has been disabled due to numerous issues that will lead this to not doing what is expected of it.

    No compiler or linker flags have been added at this time, you will need to specify the relevant flag to get the compiler to link dynamically against Phobos.

  2. The $DUB_BUILD_PATH variable was added

    The $DUB_BUILD_PATH variable is now defined inside the postBuildCommands section. It contains the absolute path in which the package was built, and can be used to copy by-products of the build process to their intended locations.

    For example, if an executable exports symbols, you will want to make the resulting import library and symbols export file available somewhere. That can be done with a dub.json section like this:

        "postBuildCommands-windows": [
            "copy /y $DUB_BUILD_PATH\\$DUB_TARGET_NAME.lib $PACKAGE_DIR\\lib"
            "copy /y $DUB_BUILD_PATH\\$DUB_TARGET_NAME.exp $PACKAGE_DIR\\lib"
        ],
    
  3. Command environment variable substitution changed

    Now users can use the documented predefined variables inside custom command directives without the need for a wrapper shell script.

    Before this would have failed:

    "preBuildCommands": ["$DC -run foo.d"]
    

    unless DC was defined as environment variable outside DUB.

    It was before possible to run a script that used the $DC environment variable or on POSIX escape the $ with $$DC to make the shell substitute the variable. These workarounds are no longer needed now.

    API change: none of the different command directives are no longer substituted with the process environment variables. You now access the raw commands as provided by the user in the recipe. dub describe has been adjusted and now also processes the predefined environment variables as well as the process environment variables.


List of all bug fixes and enhancements in D 2.098.0:

DMD Compiler regression fixes

  1. Bugzilla 13009: [REG2.064] inout overload conflicts with non-inout when used via alias this
  2. Bugzilla 21238: -deps considers only the first instantiation site of a template for dependencies
  3. Bugzilla 21850: [REG2.093] Template inference of pure not working
  4. Bugzilla 22035: [REG 2.097][ICE] Segmentation fault parsing invalid case statement
  5. Bugzilla 22048: [REG2.095] alias a = int p; compiles
  6. Bugzilla 22054: Referencing a fwd-declared field results in many error messages
  7. Bugzilla 22075: [Reg 2.068] "AA key type S should have 'size_t toHash() const nothrow @safe' if opEquals defined" is not triggered if any field of S has its own 'alias this'
  8. Bugzilla 22084: [REG 2.097] Segmentation fault passing non-pod struct as variadic argument
  9. Bugzilla 22086: importC: RangeError@src/dmd/dscope.d(469): Range violation
  10. Bugzilla 22118: Const union causes false multiple-initialization error in constructor
  11. Bugzilla 22121: [REG 2.097][ICE] Segmentation fault in in dmd.dsymbol.ScopeDsymbol.addAccessiblePackage
  12. Bugzilla 22122: [REG 2.097][ICE] Segmentation fault in in dmd.access.hasPackageAccess
  13. Bugzilla 22133: [REG2.097] Breaking change in DotTemplateExp type semantics leading to e.g. isInputRange regression
  14. Bugzilla 22157: Bad diagnostic for static/non-static overload resolution conflict
  15. Bugzilla 22170: interface thunk doesn't set EBX to GOT
  16. Bugzilla 22196: importC: Error: found const when expecting )in __attribute__
  17. Bugzilla 22205: catch(Exception) not longer working in debug blocks
  18. Bugzilla 22214: Regression 2.097.0: __traits(compiles) doesn't notice invalid getMember that yields type
  19. Bugzilla 22224: [REG 2.097.0] compiler segfaults with -profile
  20. Bugzilla 22226: [REG 2.095.1] __ctfe + function call in conditional expression used to initialize struct member in constructor causes ICE
  21. Bugzilla 22228: [CTFE] taking address of immutable in frame function causes ICE on Unix platforms
  22. Bugzilla 22292: REG[2.084.1] Recursive class literal segfaults compiler

DMD Compiler bug fixes

  1. Bugzilla 13165: Using -profile does extra control flow analysis, leading to spurious statement is not reachable warning
  2. Bugzilla 14064: Error message about @ attributes incomplete.
  3. Bugzilla 15631: gdb: Parent's scope not considered for symbol lookup
  4. Bugzilla 16274: The curses of debugging: short argument passed in 16-bit register, against ABI
  5. Bugzilla 17041: foreach-ref can't use to static array's AliasSeq
  6. Bugzilla 20150: -dip1000 defeated by pure
  7. Bugzilla 20245: DIP1000: Should infer scope when taking address of ref
  8. Bugzilla 21209: scope attribute inference with does not work well with foreach
  9. Bugzilla 21868: DIP1000 doesn't catch pointer to struct temporary
  10. Bugzilla 21905: case of IFTI failure when combining ref, and alias this on a static instance
  11. Bugzilla 21912: delegate assigned to return scope variable needs closure
  12. Bugzilla 21928: Wrong location for "array literal in @nogc function main may cause GC allocation" error
  13. Bugzilla 21931: importC: 'alias time_t = time_t;' cannot alias itself, use a qualified name to create an overload set
  14. Bugzilla 21932: importC: enum 'ENUM' conflicts with enum 'ENUM'
  15. Bugzilla 21933: importC: struct parameters: AssertError@src/dmd/typesem.d(1890): Assertion failure
  16. Bugzilla 21934: importC: Support asm labels to specify the assembler name to use for a C symbol
  17. Bugzilla 21937: importC: Support parsing __attribute specifiers
  18. Bugzilla 21939: Duplicate error messages for wrong aggregate in 'static foreach'
  19. Bugzilla 21942: importC: Support parsing __inline__ keyword
  20. Bugzilla 21944: importC: Support parsing # line marker directive extensions
  21. Bugzilla 21945: importC AssertError@src/dmd/dsymbolsem.d(4787): Assertion failure
  22. Bugzilla 21946: importC: Support parsing __extension__ keyword
  23. Bugzilla 21948: importC: Support declaring local variables of typedef types
  24. Bugzilla 21949: noreturn doesn't follow covariance rules
  25. Bugzilla 21951: Segfault on noreturn.init
  26. Bugzilla 21962: importC: Empty enums are accepted as valid code
  27. Bugzilla 21963: importC: Support declaring union types
  28. Bugzilla 21965: importC: Anonymous top-level struct or union triggers [email protected](4787)
  29. Bugzilla 21967: importC: Error function without 'this' cannot be 'const'
  30. Bugzilla 21968: importC: struct fields: AssertError@src/dmd/typesem.d(1890): Assertion failure
  31. Bugzilla 21970: importC: Error: variable extern symbols cannot have initializers
  32. Bugzilla 21973: importC: AssertError@src/dmd/dsymbolsem.d(4307): Assertion failure
  33. Bugzilla 21976: importC: does not distinguish between cast-expression and unary-expression correctly
  34. Bugzilla 21977: importC: Global declarations are thread-local by default
  35. Bugzilla 21982: importC: Error: variable no definition of struct
  36. Bugzilla 21985: "goto" errors with unexistent label report wrong/misleading line
  37. Bugzilla 21992: importC: Error: variable is used as a type
  38. Bugzilla 21993: Cannot cast to noreturn
  39. Bugzilla 21994: (char*)"string" fails to compile
  40. Bugzilla 22005: ICE: Segmentation fault with static foreach and -betterC
  41. Bugzilla 22006: static foreach and foreach over tuple doesn't work on 16-bit
  42. Bugzilla 22007: static foreach: cannot implicitly convert expression Tuple4(0LU, 1) of type Tuple4 to int
  43. Bugzilla 22019: case 1,: allowed by grammar but not DMD
  44. Bugzilla 22028: importC: Parser accepts initializers for struct members
  45. Bugzilla 22029: importC: Parser accepts storage-class specifiers for fields
  46. Bugzilla 22030: importC: Wrong error with bad declarator
  47. Bugzilla 22032: importC: infinite loop: illegal combination of type specifiers
  48. Bugzilla 22053: catch { not rejected while in a template
  49. Bugzilla 22060: importC: Multiple forward declarations result in error struct conflicts with struct
  50. Bugzilla 22063: importC: Error: undefined identifier 'var' with pointer-to-typedef type
  51. Bugzilla 22066: importC: Error: expression expected, not ';' using (postfix-expression)++
  52. Bugzilla 22067: importC: cast-expression accepted as lvalue in assignment-expression
  53. Bugzilla 22068: importC: cast-expression accepted as lvalue in unary-expression
  54. Bugzilla 22069: importC: Error: found '&' instead of statement
  55. Bugzilla 22070: importC: Error: string literal is not an lvalue
  56. Bugzilla 22071: importC: Error: struct literal is not an lvalue
  57. Bugzilla 22073: importC: Error: found '.' when expecting ';' following compound literal
  58. Bugzilla 22079: importC: Error: '=', ';' or ',' expected taking sizeof compound literal
  59. Bugzilla 22080: ImportC: Error: cannot implicitly convert expression of type 'extern(C) function' to 'function'
  60. Bugzilla 22088: ImportC: C11 6.3 semantics on implicit conversions is not implemented
  61. Bugzilla 22102: importC: Error: function is used as a type
  62. Bugzilla 22103: importC: Parser accepts wrong syntax for array declarators
  63. Bugzilla 22106: importC: Error: variable 'var' no definition of struct 'type'
  64. Bugzilla 22126: -checkaction=context should not print overlapped struct members
  65. Bugzilla 22144: ICE(dcast.d): Floating point exception in castTo::CastTo::visit(Expression*) at dmd/dcast.d:1702
  66. Bugzilla 22149: TypeInfo_Struct names aren't unique, leading to botched equality semantics
  67. Bugzilla 22150: TypeInfo_Class names aren't unique, leading to botched equality semantics
  68. Bugzilla 22160: importC: Error: redeclaring module test as struct test
  69. Bugzilla 22179: core.stdcpp.utility is missing in dmd binary dist
  70. Bugzilla 22180: .alignof not working for globals
  71. Bugzilla 22182: importC: Error: expression expected, not ) when casting pointer with redundant parens.
  72. Bugzilla 22209: NRVO variable detection ignoring alias this conversion => segfaults
  73. Bugzilla 22246: importC: C11 does not allow _Alignof (expression)
  74. Bugzilla 22250: ImportC: Array subscripts do not comply with C standard.
  75. Bugzilla 22252: ImportC: Array, Function parameter types should be converted to pointers
  76. Bugzilla 22253: ImportC expressions inadvertently supporting D properties
  77. Bugzilla 22262: importC: Error: incompatible types for '(buf) is (0)': 'ubyte*' and 'int'
  78. Bugzilla 22263: ImportC: function and variable re-declarations should be allowed
  79. Bugzilla 22264: importC: Error: '=', ';' or ',' expected using K&R function syntax
  80. Bugzilla 22265: importC: Error: cannot modify 'const' expression
  81. Bugzilla 22274: importC: [ICE]: 4 identifiers does not match 3 declarations using K&R syntax
  82. Bugzilla 22275: importC: Error: incompatible types for (dest) !is (buf): char* and char[1]
  83. Bugzilla 22286: importC: (identifier)(other_identifier) incorrectly parsed as a cast-expression
  84. Bugzilla 22294: importC: enums aren’t placed in surrounding namespace.
  85. Bugzilla 22303: ImportC: pragma directives should be ignored
  86. Bugzilla 22304: importC: parsing gnu-style attributes fails if return type is pointer
  87. Bugzilla 22312: importC: redundant typedefs are rejected
  88. Bugzilla 22313: ImportC: account for ( ) when doing lookahead on assignment-expressions
  89. Bugzilla 22314: ImportC: fails to parse gnu attributes on enum members
  90. Bugzilla 22321: ImportC: non-static arrays can’t be initialized by an initializer list.
  91. Bugzilla 22322: ImportC: struct with floating point members causes problems with generated toHash() function
  92. Bugzilla 22326: ImportC: struct with flexible array member is incorrectly handled
  93. Bugzilla 22329: DMD and LDC2 Segumentation Faults due to alias this on private field + special names
  94. Bugzilla 22333: ImportC: fails to parse enumerators with = and gnu attributes
  95. Bugzilla 22373: Glue layer rejects cast from noreturn to other type

DMD Compiler enhancements

  1. Bugzilla 15889: Array bounds check should report index and length
  2. Bugzilla 16001: Lambda syntax: forbid use with FunctionLiteralBody: (x) => {assert(x);}
  3. Bugzilla 16689: Errors in instantiated mixin templates should show instantiation point
  4. Bugzilla 17400: put a new line before "candidates are:" in error messages
  5. Bugzilla 18907: Support cross-compiling
  6. Bugzilla 21885: Bad diagnostic: struct is not copyable because it is annotated @disable
  7. Bugzilla 21997: CTFE should allow function pointer casts with different attributes
  8. Bugzilla 22038: final switch error message should report all missing enum members
  9. Bugzilla 22115: Optimize if (s.a == 3 ? s : null) to if (s.a == 3)
  10. Bugzilla 22138: foreach cannot declare the loop variables as scope
  11. Bugzilla 22227: if (scope f = x()) and while (scope f = x()) do not parse

Phobos regression fixes

  1. Bugzilla 21920: [REG master] Error: auto can only be used as part of auto ref for template function parameters
  2. Bugzilla 22056: [Reg 2.074] std.traits.isFloatingPoint, isNumeric, isUnsigned, & isSigned should never be true for SIMD vectors
  3. Bugzilla 22057: [Reg 2.074] std.traits.isNumeric & isUnsigned should not be true for enum types with character base types
  4. Bugzilla 22058: [Reg 2.074] std.traits.isNumeric & isSigned should not be true for complex or imaginary types
  5. Bugzilla 22093: [Reg 2.097] std.typecons.RefCounted!T for struct T without an explicit toString or alias this previously could be converted to string even when uninitialized but now cannot be
  6. Bugzilla 22125: std.process.Config was changed to a struct but miss operator overloads, leading to user code breakage.
  7. Bugzilla 22176: Nullable creates autogenerated opAssign, triggering invariants

Phobos bug fixes

  1. Bugzilla 19727: std.algorithm.endsWith fails to compile while startsWith succeeds
  2. Bugzilla 20393: formattedRead accepts input, that should be rejected
  3. Bugzilla 20937: std.range.array of a lengthless range with indirection is not @safe
  4. Bugzilla 21916: Error message is obfuscated when using wrong format specifier at compile-time
  5. Bugzilla 22001: Equality of std.conv.toChars() results for radix 10 depends on uninitialized bytes
  6. Bugzilla 22077: std.sumtype support for copy constructors is incomplete
  7. Bugzilla 22101: Nullable.get(fallback) cannot be used with non-@safe/pure/nothrow types
  8. Bugzilla 22110: isCallable fails for template opCall without any templated argument
  9. Bugzilla 22140: FunctionTypeOf fails for template opCall without any templated argument
  10. Bugzilla 22146: std.algorithm.searching.findAdjacent() can fall off end of function
  11. Bugzilla 22222: Custom unittest runner on phobos fails due to segfault on fork() exiting

Phobos enhancements

  1. Bugzilla 16210: std.utf.byUTF can be made into a bidirectional range
  2. Bugzilla 16218: Windows std.file.readImpl should be marked @system
  3. Bugzilla 18632: enable use of fromStringz with char[n]
  4. Bugzilla 20665: std.concurrency.spawn should document not working with delegates
  5. Bugzilla 21926: Allow leading zeros in std.conv.octal
  6. Bugzilla 22100: Support chained assignment of Nullable
  7. Bugzilla 22225: SumType: Some assignments should be able to execute in safe code

Druntime regression fixes

  1. Bugzilla 21110: OOB memory access, safety violation
  2. Bugzilla 22178: [REG 2.097] Compilers do not compile on Musl Libc

Druntime bug fixes

  1. Bugzilla 9799: Missing aliases and enums in druntime imports
  2. Bugzilla 14439: aa's keys, values not usable in @safe context
  3. Bugzilla 21550: core.memory.__delete does not actually work
  4. Bugzilla 21983: dup leaves a partially constructed array if postblit/copy ctor throws
  5. Bugzilla 21996: -checkaction=context triggers InvalidMemoryOperationError in finalizer
  6. Bugzilla 22024: hashOf does not work on enum types whose base type is a SIMD vector
  7. Bugzilla 22026: checkaction=context: Exception thrown by toString hides assertion failures
  8. Bugzilla 22076: hashOf(S) can segfault if S.toHash is forwarded via 'alias this' to a receiver which may be null
  9. Bugzilla 22081: DWARF v5 support is utterly broken - 'illegal instruction' when throwing exceptions
  10. Bugzilla 22085: checkaction=context doesn't support extern(C++) classes
  11. Bugzilla 22107: [scope][dip1000] Can't .dup an array of structs with impure copy constructor
  12. Bugzilla 22143: Throwable ctor doesn't increment chained exception's ref count
  13. Bugzilla 22166: On OpenBSD and Android make core.sys.posix.arpa.inet: htonl, htons, ntohl, & ntohs work correctly on big endian architectures
  14. Bugzilla 22167: OpenBSD core.sys.posix.semaphore: sem_t should be a pointer to an opaque struct
  15. Bugzilla 22168: Fix non-compiling ELF32_M_INFO & ELF64_M_INFO in core.sys..sys.elf32 & core.sys..sys.elf64 for DragonFlyBSD, FreeBSD, NetBSD, & OpenBSD
  16. Bugzilla 22218: Dynamic casts across binary boundaries can easily fail

Druntime enhancements

  1. Bugzilla 22169: Mark as pure core.sys.posix.string: memccpy, stpcpy, stpncpy, strnlen

dlang.org bug fixes

  1. Bugzilla 3345: Static and nonstatic methods with the same name should be allowed
  2. Bugzilla 20557: Spec does not allow StringPostfix after DelimitedString or TokenString while implementation does
  3. Bugzilla 21125: Typo in std.range.refRange documentation for opIndex
  4. Bugzilla 21906: obscure sentence in the introduction to phases of compilation
  5. Bugzilla 21935: Broken Link in Lazy Evaluation Article
  6. Bugzilla 22229: Struct initialization via constructor missing from language spec

dlang.org enhancements

  1. Bugzilla 21495: File.readf documentation does not state what what is returned.
  2. Bugzilla 21600: Regex.namedCaptures is undocumented

Installer bug fixes

  1. Bugzilla 21488: Bundled 32-bit dlang tools (ddemangle, dustmite, rdmd) segfault on startup

Contributors to this release (62)

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

previous version: 2.097.0