Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package dmd for openSUSE:Factory checked in at 2024-05-06 17:54:57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/dmd (Old) and /work/SRC/openSUSE:Factory/.dmd.new.1880 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "dmd" Mon May 6 17:54:57 2024 rev:38 rq:1172125 version:2.108.1 Changes: -------- --- /work/SRC/openSUSE:Factory/dmd/dmd.changes 2024-04-03 17:21:39.508245541 +0200 +++ /work/SRC/openSUSE:Factory/.dmd.new.1880/dmd.changes 2024-05-06 17:56:15.841664630 +0200 @@ -1,0 +2,19 @@ +Mon May 6 07:52:44 UTC 2024 - Andrea Manzini <andrea.manz...@suse.com> + +- Update to version 2.108.1 + * DMD Compiler regression fixes + + Bugzilla 23657: [REG2.101] Incorrect error escape reference to stack allocated value + + Bugzilla 24436: a array be overwritten when other array be written + + Bugzilla 24479: [REG2.104] Error on getAttributes on getOverloads of templates + + Bugzilla 24505: [REG2.108] ImportC: Function-like macros (newly translated to templates) may collide with regular symbols + + Bugzilla 24519: compiler segfault on default argument with slice operator [] + * DMD Compiler bug fixes + + Bugzilla 24495: ImportC: Struct initialization expression fails to initialize field + + Bugzilla 24509: importC cannot handle _stdcall Function Calling Convention with single heading underscore + + Bugzilla 24511: __stdcall functions from C are extern(C) in D. + * Phobos regression fixes + + Bugzilla 24481: retro no longer works with types that support assignment but not moving + * Druntime regression fixes + + Bugzilla 24498: Multidimensional array not scanned by GC + +------------------------------------------------------------------- Old: ---- dmd-2.108.0.tar.gz phobos-2.108.0.tar.gz New: ---- dmd-2.108.1.tar.gz phobos-2.108.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ dmd.spec ++++++ --- /var/tmp/diff_new_pack.TGD1Sx/_old 2024-05-06 17:56:16.369683851 +0200 +++ /var/tmp/diff_new_pack.TGD1Sx/_new 2024-05-06 17:56:16.373683997 +0200 @@ -29,7 +29,7 @@ BuildRequires: phobos-devel-static %endif Name: dmd -Version: 2.108.0 +Version: 2.108.1 Release: 0 Summary: D Programming Language 2.0 License: BSL-1.0 ++++++ dmd-2.108.0.tar.gz -> dmd-2.108.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dmd-2.108.0/.github/workflows/main.yml new/dmd-2.108.1/.github/workflows/main.yml --- old/dmd-2.108.0/.github/workflows/main.yml 2024-04-01 20:40:58.000000000 +0200 +++ new/dmd-2.108.1/.github/workflows/main.yml 2024-05-02 08:08:45.000000000 +0200 @@ -32,11 +32,12 @@ os: ubuntu-22.04 model: 32 host_dmd: dmd - - job_name: Ubuntu 22.04 x86, DMD (coverage) - os: ubuntu-22.04 - model: 32 - host_dmd: dmd - coverage: true + # Disabled because of failure https://issues.dlang.org/show_bug.cgi?id=24518 + # - job_name: Ubuntu 22.04 x86, DMD (coverage) + # os: ubuntu-22.04 + # model: 32 + # host_dmd: dmd + # coverage: true - job_name: Ubuntu 22.04 x86, DMD (bootstrap) os: ubuntu-22.04 model: 32 @@ -51,13 +52,12 @@ # macOS - job_name: macOS 13 x64, DMD (latest) os: macos-13 - # FIXME: Revert this back to "dmd" after 2.107.1 is released. - host_dmd: ldc - - job_name: macOS 13 x64, DMD (coverage) - os: macos-13 - # FIXME: Revert this back to "dmd" after 2.107.1 is released. - host_dmd: ldc - coverage: true + host_dmd: dmd + # Disabled because of failure https://issues.dlang.org/show_bug.cgi?id=24518 + # - job_name: macOS 13 x64, DMD (coverage) + # os: macos-13 + # host_dmd: dmd + # coverage: true - job_name: macOS 12 x64, DMD (bootstrap) os: macos-12 # de-facto bootstrap version on OSX diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dmd-2.108.0/VERSION new/dmd-2.108.1/VERSION --- old/dmd-2.108.0/VERSION 2024-04-01 20:40:58.000000000 +0200 +++ new/dmd-2.108.1/VERSION 2024-05-02 08:08:45.000000000 +0200 @@ -1 +1 @@ -v2.108.0 +v2.108.1 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dmd-2.108.0/changelog/dmd.classinfo.dd new/dmd-2.108.1/changelog/dmd.classinfo.dd --- old/dmd-2.108.0/changelog/dmd.classinfo.dd 2024-04-01 20:40:58.000000000 +0200 +++ new/dmd-2.108.1/changelog/dmd.classinfo.dd 1970-01-01 01:00:00.000000000 +0100 @@ -1,10 +0,0 @@ -Added .nameSig field to TypeInfo_Class in object.d - -This is a 16 byte md5 signature of the fully qualified name of the class. -It is used to compare two classes for equality, rather than comparing the -pointers with a fallback to doing a string compare on the name, which can -be rather slow. - -The result is both druntime and phobos will need to be recompiled to be -compatible with this change. Any libraries will need to be recompiled -as well. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dmd-2.108.0/changelog/dmd.default-init.dd new/dmd-2.108.1/changelog/dmd.default-init.dd --- old/dmd-2.108.0/changelog/dmd.default-init.dd 2024-04-01 20:40:58.000000000 +0200 +++ new/dmd-2.108.1/changelog/dmd.default-init.dd 1970-01-01 01:00:00.000000000 +0100 @@ -1,44 +0,0 @@ -Keywords like `__FILE__` are always evaluated at the call site - -Default arguments for functions can contain the keywords `__FILE__`, -`__FILE_FULL_PATH__`, `__MODULE__`, `__LINE__`, `__FUNCTION__` -and `__PRETTY_FUNCTION__`. They are now evaluated at the source location -of the calling function in more complex expressions as long as used in -an initializer, directly or not. Previously they had to be used directly -in the initializer to be evaluated at the call site. Here are some -examples, where more complex initializers are now evaluated at the -call site: - ---- -void func1(const(char)* file = __FILE__.ptr, size_t line = __LINE__) -{ - // This now prints the filename of the calling function. - // Previously it was the filename of func1 itself. - printf("%s:%zd\n", file, line); -} - -struct Loc -{ - string file; - size_t line; -} - -void func2(Loc loc = Loc(__FILE__, __LINE__)) -{ - // Variable loc now contains file and line of the calling function. - // Previously it was the location of func2. - writeln(loc.file, ":", loc.line); -} - -Loc defaultLoc(string file = __FILE__, size_t line = __LINE__) -{ - return Loc(file, line); -} - -void func3(Loc loc = defaultLoc) -{ - // Variable loc contains file and line of the calling function of - // func3 and not the location of func3 or defaultLoc. - writeln(loc.file, ":", loc.line); -} ---- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dmd-2.108.0/changelog/dmd.hexstring-cast.dd new/dmd-2.108.1/changelog/dmd.hexstring-cast.dd --- old/dmd-2.108.0/changelog/dmd.hexstring-cast.dd 2024-04-01 20:40:58.000000000 +0200 +++ new/dmd-2.108.1/changelog/dmd.hexstring-cast.dd 1970-01-01 01:00:00.000000000 +0100 @@ -1,29 +0,0 @@ -Hex strings now convert to integer arrays - -Hex strings are the most efficient way to embed binary data into source files. -However, they couldn't easily be used to initialize a `short[]`, `int[]` or `long[]` because re-interpret casting arrays is not allowed during CTFE. -Now, hex strings implicitly convert to all integer arrays. -A big endian byte order is assumed, consistent with how integer literals are written. - ---- -immutable uint[] data = x"AABBCCDD"; - -static assert(data[0] == 0xAABBCCDD); ---- - -Character postfixes can now also be used to explicitly set an element size of 2 or 4. - ---- -immutable ushort[] f = x"80 3F"w; -static assert(f[0] == 0x803F); - -immutable ubyte[] g = x"80 35"w; // error: size mismatch ---- - -Formerly, they would pad each byte with 1 or 3 zeros, which did not serve a purpose (See [Issue 24363](https://issues.dlang.org/show_bug.cgi?id=24363)). - -If the string's byte length is not a multiple of the target element size, it is an error: - ---- -immutable ushort[] e = x"AABBCC"w; // Error, 3 bytes is not a multiple of `ushort.sizeof` ---- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dmd-2.108.0/changelog/dmd.ies.dd new/dmd-2.108.1/changelog/dmd.ies.dd --- old/dmd-2.108.0/changelog/dmd.ies.dd 2024-04-01 20:40:58.000000000 +0200 +++ new/dmd-2.108.1/changelog/dmd.ies.dd 1970-01-01 01:00:00.000000000 +0100 @@ -1,18 +0,0 @@ -Add support for Interpolated Expression Sequences - -Interpolated Expression Sequences are a way to implement things like string interpolation in library code. Three forms of literals are added: - -``` -i"Content $(a + 4)" -i`Content $(a + 4)` -iq{Content $(a + 4)} -``` - -all provide the same thing: a tuple that can be passed to other functions, like `writeln` from `std.stdio` and `text` from `std.conv`: - -``` -int a = 6; -writeln(i"Content $(a + 4)"); // prints "Content 10" -``` - -You can also pass them to other functions which understand the types in the new `core.interpolation` module. Numerous examples can be found documentation of that module or in this repository: https://github.com/adamdruppe/interpolation-examples/ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dmd-2.108.0/changelog/dmd.named-arguments.dd new/dmd-2.108.1/changelog/dmd.named-arguments.dd --- old/dmd-2.108.0/changelog/dmd.named-arguments.dd 2024-04-01 20:40:58.000000000 +0200 +++ new/dmd-2.108.1/changelog/dmd.named-arguments.dd 1970-01-01 01:00:00.000000000 +0100 @@ -1,41 +0,0 @@ -Named arguments for functions have been implemented and documented - -When calling a function, arguments may be preceded with a parameter name for purposes of clarity and flexible ordering. -Consequently, default arguments need not be at the end of the parameter list anymore. - ---- -void createWindow(bool fullScreen = false, int width, int height, string title); - -void main() -{ - createWindow(title: "Skynet", width: 1280, height: 720); -} ---- - -Named arguments can also be used in struct/union literals. -A union can now be initialized by setting a field different than the first one. - ---- -union U -{ - float asFloat; - uint asInt; -} - -auto u0 = U(1.0); // this sets the `asFloat` field -auto u1 = U(asInt: 0x3F800000); // formerly not possible ---- - -Relevant specification pages are: -$(UL - $(LI $(DDSUBLINK spec/struct, struct-literal, Struct Literals)) - $(LI $(DDSUBLINK spec/struct, anonymous, Anonymous Structs and Unions)) - $(LI $(DDSUBLINK spec/expression, argument-parameter-matching, Matching Arguments to Parameters)) - $(LI $(DDSUBLINK spec/function, function-overloading, Function Overloading)) -) - -Note that the implementation for regular functions and struct literals has been around since dmd 2.103, but it was undocumented and wouldn't work with template functions. - -This implements [DIP1030](https://www.dlang.org/dips/1030) for *function arguments*, but named *template arguments* are not implemented yet. -Also, there are still implementation details to be ironed out which the DIP doesn't specify, such as how named arguments interact with tuples. -For more information, see: [Named Arguments Status Update](https://forum.dlang.org/post/bynneksajyfyadwnd...@forum.dlang.org) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dmd-2.108.0/compiler/src/dmd/cparse.d new/dmd-2.108.1/compiler/src/dmd/cparse.d --- old/dmd-2.108.0/compiler/src/dmd/cparse.d 2024-04-01 20:40:58.000000000 +0200 +++ new/dmd-2.108.1/compiler/src/dmd/cparse.d 2024-05-02 08:08:45.000000000 +0200 @@ -1919,6 +1919,14 @@ auto s = cparseFunctionDefinition(id, dt.isTypeFunction(), specifier); typedefTab.setDim(typedefTabLengthSave); symbols = symbolsSave; + if (specifier.mod & MOD.x__stdcall) + { + // If this function is __stdcall, wrap it in a LinkDeclaration so that + // it's extern(Windows) when imported in D. + auto decls = new AST.Dsymbols(1); + (*decls)[0] = s; + s = new AST.LinkDeclaration(s.loc, LINK.windows, decls); + } symbols.push(s); return; } @@ -2071,13 +2079,14 @@ } } s = applySpecifier(s, specifier); - if (level == LVL.local) + if (level == LVL.local || (specifier.mod & MOD.x__stdcall)) { - // Wrap the declaration in `extern (C) { declaration }` + // Wrap the declaration in `extern (C/Windows) { declaration }` // Necessary for function pointers, but harmless to apply to all. auto decls = new AST.Dsymbols(1); (*decls)[0] = s; - s = new AST.LinkDeclaration(s.loc, linkage, decls); + const lkg = specifier.mod & MOD.x__stdcall ? LINK.windows : linkage; + s = new AST.LinkDeclaration(s.loc, lkg, decls); } symbols.push(s); } @@ -5860,13 +5869,15 @@ const(char)* endp = &slice[length - 7]; + AST.Dsymbols newSymbols; + size_t[void*] defineTab; // hash table of #define's turned into Symbol's - // indexed by Identifier, returns index into symbols[] + // indexed by Identifier, returns index into newSymbols[] // The memory for this is leaked - void addVar(AST.Dsymbol s) + void addSym(AST.Dsymbol s) { - //printf("addVar() %s\n", s.toChars()); + //printf("addSym() %s\n", s.toChars()); if (auto v = s.isVarDeclaration()) v.isCmacro(true); // mark it as coming from a C #define /* If it's already defined, replace the earlier @@ -5874,13 +5885,22 @@ */ if (size_t* pd = cast(void*)s.ident in defineTab) { - //printf("replacing %s\n", v.toChars()); - (*symbols)[*pd] = s; + //printf("replacing %s\n", s.toChars()); + newSymbols[*pd] = s; return; } - assert(symbols, "symbols is null"); - defineTab[cast(void*)s.ident] = symbols.length; - symbols.push(s); + defineTab[cast(void*)s.ident] = newSymbols.length; + newSymbols.push(s); + } + + void removeSym(Identifier ident) + { + //printf("removeSym() %s\n", ident.toChars()); + if (size_t* pd = cast(void*)ident in defineTab) + { + //printf("removing %s\n", ident.toChars()); + newSymbols[*pd] = null; + } } while (p < endp) @@ -5924,7 +5944,7 @@ */ AST.Expression e = new AST.IntegerExp(scanloc, intvalue, t); auto v = new AST.VarDeclaration(scanloc, t, id, new AST.ExpInitializer(scanloc, e), STC.manifest); - addVar(v); + addSym(v); ++p; continue; } @@ -5947,7 +5967,7 @@ */ AST.Expression e = new AST.RealExp(scanloc, floatvalue, t); auto v = new AST.VarDeclaration(scanloc, t, id, new AST.ExpInitializer(scanloc, e), STC.manifest); - addVar(v); + addSym(v); ++p; continue; } @@ -5965,7 +5985,7 @@ */ AST.Expression e = new AST.StringExp(scanloc, str[0 .. len], len, 1, postfix); auto v = new AST.VarDeclaration(scanloc, null, id, new AST.ExpInitializer(scanloc, e), STC.manifest); - addVar(v); + addSym(v); ++p; continue; } @@ -6001,7 +6021,7 @@ AST.TemplateParameters* tpl = new AST.TemplateParameters(); AST.Expression constraint = null; auto tempdecl = new AST.TemplateDeclaration(exp.loc, id, tpl, constraint, decldefs, false); - addVar(tempdecl); + addSym(tempdecl); ++p; continue; } @@ -6092,7 +6112,7 @@ AST.Dsymbols* decldefs = new AST.Dsymbols(); decldefs.push(fd); auto tempdecl = new AST.TemplateDeclaration(exp.loc, id, tpl, null, decldefs, false); - addVar(tempdecl); + addSym(tempdecl); ++p; continue; @@ -6103,6 +6123,14 @@ } } } + else if (p[0 .. 6] == "#undef") + { + p += 6; + nextToken(); + //printf("undef %s\n", token.toChars()); + if (token.value == TOK.identifier) + removeSym(token.ident); + } // scan to end of line while (*p) ++p; @@ -6110,6 +6138,16 @@ scanloc.linnum = scanloc.linnum + 1; } + if (newSymbols.length) + { + assert(symbols, "symbols is null"); + symbols.reserve(newSymbols.length); + + foreach (sym; newSymbols) + if (sym) // undefined entries are null + symbols.push(sym); + } + scanloc = scanlocSave; eSink = save; defines = buf; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dmd-2.108.0/compiler/src/dmd/escape.d new/dmd-2.108.1/compiler/src/dmd/escape.d --- old/dmd-2.108.0/compiler/src/dmd/escape.d 2024-04-01 20:40:58.000000000 +0200 +++ new/dmd-2.108.1/compiler/src/dmd/escape.d 2024-05-02 08:08:45.000000000 +0200 @@ -1542,7 +1542,7 @@ * e = expression to be returned by value * er = where to place collected data * live = if @live semantics apply, i.e. expressions `p`, `*p`, `**p`, etc., all return `p`. - * retRefTransition = if `e` is returned through a `return ref scope` function call + * retRefTransition = if `e` is returned through a `return (ref) scope` function call */ public void escapeByValue(Expression e, EscapeByResults* er, bool live = false, bool retRefTransition = false) @@ -1786,7 +1786,7 @@ } } else - escapeByValue(arg, er, live, retRefTransition); + escapeByValue(arg, er, live, true); } else if (psr == ScopeRef.ReturnRef || psr == ScopeRef.ReturnRef_Scope) { @@ -1941,7 +1941,7 @@ * e = expression to be returned by 'ref' * er = where to place collected data * live = if @live semantics apply, i.e. expressions `p`, `*p`, `**p`, etc., all return `p`. - * retRefTransition = if `e` is returned through a `return ref scope` function call + * retRefTransition = if `e` is returned through a `return (ref) scope` function call */ private void escapeByRef(Expression e, EscapeByResults* er, bool live = false, bool retRefTransition = false) @@ -2189,7 +2189,7 @@ import dmd.root.array: Array; /** - * Whether the variable / expression went through a `return ref scope` function call + * Whether the variable / expression went through a `return (ref) scope` function call * * This is needed for the dip1000 by default transition, since the rules for * disambiguating `return scope ref` have changed. Therefore, functions in legacy code @@ -2197,6 +2197,10 @@ * are being escaped, which is an error even in `@system` code. By keeping track of this * information, variables escaped through `return ref` can be treated as a deprecation instead * of error, see test/fail_compilation/dip1000_deprecation.d + * + * Additionally, return scope can be inferred wrongly instead of scope, in which + * case the code could give false positives even without @safe or dip1000: + * https://issues.dlang.org/show_bug.cgi?id=23657 */ private Array!bool refRetRefTransition; private Array!bool expRetRefTransition; @@ -2218,7 +2222,7 @@ * Escape variable `v` by reference * Params: * v = variable to escape - * retRefTransition = `v` is escaped through a `return ref scope` function call + * retRefTransition = `v` is escaped through a `return (ref) scope` function call */ void pushRef(VarDeclaration v, bool retRefTransition) { @@ -2230,7 +2234,7 @@ * Escape a reference to expression `e` * Params: * e = expression to escape - * retRefTransition = `e` is escaped through a `return ref scope` function call + * retRefTransition = `e` is escaped through a `return (ref) scope` function call */ void pushExp(Expression e, bool retRefTransition) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dmd-2.108.0/compiler/src/dmd/expressionsem.d new/dmd-2.108.1/compiler/src/dmd/expressionsem.d --- old/dmd-2.108.0/compiler/src/dmd/expressionsem.d 2024-04-01 20:40:58.000000000 +0200 +++ new/dmd-2.108.1/compiler/src/dmd/expressionsem.d 2024-05-02 08:08:45.000000000 +0200 @@ -5335,7 +5335,8 @@ lowering = new DotIdExp(exp.loc, lowering, Id.object); auto tbn = exp.type.nextOf(); - while (tbn.ty == Tarray) + size_t i = nargs; + while (tbn.ty == Tarray && --i) tbn = tbn.nextOf(); auto unqualTbn = tbn.unqualify(MODFlags.wild | MODFlags.const_ | MODFlags.immutable_ | MODFlags.shared_); @@ -15331,8 +15332,10 @@ Expression visitSlice(SliceExp exp) { exp.e1 = exp.e1.resolveLoc(loc, sc); - exp.lwr = exp.lwr.resolveLoc(loc, sc); - exp.upr = exp.upr.resolveLoc(loc, sc); + if (exp.lwr) + exp.lwr = exp.lwr.resolveLoc(loc, sc); + if (exp.upr) + exp.upr = exp.upr.resolveLoc(loc, sc); return exp; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dmd-2.108.0/compiler/src/dmd/initsem.d new/dmd-2.108.1/compiler/src/dmd/initsem.d --- old/dmd-2.108.0/compiler/src/dmd/initsem.d 2024-04-01 20:40:58.000000000 +0200 +++ new/dmd-2.108.1/compiler/src/dmd/initsem.d 2024-05-02 08:08:45.000000000 +0200 @@ -868,11 +868,13 @@ * by the initializer syntax. if a CInitializer has a Designator, it is probably * a nested anonymous struct */ - if (cix.initializerList.length) + int found; + foreach (dix; cix.initializerList) { - DesigInit dix = cix.initializerList[0]; Designators* dlistx = dix.designatorList; - if (dlistx && (*dlistx).length == 1 && (*dlistx)[0].ident) + if (!dlistx) + continue; + if ((*dlistx).length == 1 && (*dlistx)[0].ident) { auto id = (*dlistx)[0].ident; foreach (k, f; sd.fields[]) // linear search for now @@ -883,11 +885,18 @@ si.addInit(id, dix.initializer); ++fieldi; ++index; - continue Loop1; + ++found; + break; } } } + else { + error(ci.loc, "only 1 designator currently allowed for C struct field initializer `%s`", toChars(ci)); + } } + + if (found == cix.initializerList.length) + continue Loop1; } VarDeclaration field; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dmd-2.108.0/compiler/src/dmd/traits.d new/dmd-2.108.1/compiler/src/dmd/traits.d --- old/dmd-2.108.0/compiler/src/dmd/traits.d 2024-04-01 20:40:58.000000000 +0200 +++ new/dmd-2.108.1/compiler/src/dmd/traits.d 2024-05-02 08:08:45.000000000 +0200 @@ -1245,7 +1245,7 @@ // @@@DEPRECATION 2.100.2 if (auto td = s.isTemplateDeclaration()) { - if (td.overnext || td.overroot) + if (td.overnext) { deprecation(e.loc, "`__traits(getAttributes)` may only be used for individual functions, not the overload set `%s`", td.ident.toChars()); deprecationSupplemental(e.loc, "the result of `__traits(getOverloads)` may be used to select the desired function to extract attributes from"); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dmd-2.108.0/compiler/test/compilable/imports/test24511_c.c new/dmd-2.108.1/compiler/test/compilable/imports/test24511_c.c --- old/dmd-2.108.0/compiler/test/compilable/imports/test24511_c.c 1970-01-01 01:00:00.000000000 +0100 +++ new/dmd-2.108.1/compiler/test/compilable/imports/test24511_c.c 2024-05-02 08:08:45.000000000 +0200 @@ -0,0 +1,17 @@ +typedef void (*CFunctionPointer)(); +typedef void (__stdcall *StdCallFunctionPointer)(); + +void cFunction() +{} + +void __stdcall stdcallFunction() +{} + +void __stdcall takesCFunctionPointer(CFunctionPointer f) +{} + +void takesStdCallFunctionPointer(StdCallFunctionPointer f) +{} + +typedef void (__stdcall *StdCallFunctionPointerTakingCFunctionPointer)(CFunctionPointer f); +typedef void (*CFunctionPointerTakingStdCallFunctionPointer)(StdCallFunctionPointer f); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dmd-2.108.0/compiler/test/compilable/returnscope_without_safe.d new/dmd-2.108.1/compiler/test/compilable/returnscope_without_safe.d --- old/dmd-2.108.0/compiler/test/compilable/returnscope_without_safe.d 1970-01-01 01:00:00.000000000 +0100 +++ new/dmd-2.108.1/compiler/test/compilable/returnscope_without_safe.d 2024-05-02 08:08:45.000000000 +0200 @@ -0,0 +1,16 @@ +// Stack pointers are being escaped here, but without +// @safe and dip1000, it should still be allowed +// because return scope could have been inferred incorrectly, +// and it breaks existing code: +// https://issues.dlang.org/show_bug.cgi?id=23657 + +int* identity(return scope int* x); + +auto identityAuto(int* x) => x; + +int* f() +{ + int x; + return identity(&x); + return identityAuto(&x); +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dmd-2.108.0/compiler/test/compilable/test22727.c new/dmd-2.108.1/compiler/test/compilable/test22727.c --- old/dmd-2.108.0/compiler/test/compilable/test22727.c 2024-04-01 20:40:58.000000000 +0200 +++ new/dmd-2.108.1/compiler/test/compilable/test22727.c 2024-05-02 08:08:45.000000000 +0200 @@ -6,6 +6,10 @@ int __stdcall foostdcall2(int a) { return a; } +#if _MSC_VER +int _stdcall foostdcall3(int a) { return a; } // test issue 24509 +#endif + int __stdcall (*fp1)(int a) = &foostdcall; int (__stdcall *fp2)(int a) = &foostdcall2; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dmd-2.108.0/compiler/test/compilable/test24479.d new/dmd-2.108.1/compiler/test/compilable/test24479.d --- old/dmd-2.108.0/compiler/test/compilable/test24479.d 1970-01-01 01:00:00.000000000 +0100 +++ new/dmd-2.108.1/compiler/test/compilable/test24479.d 2024-05-02 08:08:45.000000000 +0200 @@ -0,0 +1,35 @@ +// https://issues.dlang.org/show_bug.cgi?id=24479 + +/* +TEST_OUTPUT: +--- +1 +2 +--- +*/ + +struct S +{ + @1 + S opBinary(string op: "-")(S rhs) const pure nothrow @nogc + { + return rhs; + } + @2 + S opBinary(string op: "*")(S dur) const pure nothrow @nogc + { + return dur; + } +} + +private enum hasExternalUDA(alias A) = is(A == External) || is(typeof(A) == External); + +void foo() +{ + static foreach (t; __traits(getOverloads, S, "opBinary", true)) + static foreach(attr; __traits(getAttributes, t)) + pragma(msg, attr); + + static assert(__traits(getOverloads, S, "opBinary", true).length == 2); + alias A = __traits(getAttributes, __traits(getOverloads, S, "opBinary", true)[1]); +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dmd-2.108.0/compiler/test/compilable/test24505.c new/dmd-2.108.1/compiler/test/compilable/test24505.c --- old/dmd-2.108.0/compiler/test/compilable/test24505.c 1970-01-01 01:00:00.000000000 +0100 +++ new/dmd-2.108.1/compiler/test/compilable/test24505.c 2024-05-02 08:08:45.000000000 +0200 @@ -0,0 +1,15 @@ +// https://issues.dlang.org/show_bug.cgi?id=24505 + +// PERMUTE_ARGS: + +struct stat { int x; }; + +void __stat(int x, int y); +#define stat(x, y) __stat(x, y) + +// reversed order: +#define stat2(x, y) __stat(x, y) +struct stat2 { int x; }; + +#undef stat +#undef stat2 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dmd-2.108.0/compiler/test/compilable/test24511.d new/dmd-2.108.1/compiler/test/compilable/test24511.d --- old/dmd-2.108.0/compiler/test/compilable/test24511.d 1970-01-01 01:00:00.000000000 +0100 +++ new/dmd-2.108.1/compiler/test/compilable/test24511.d 2024-05-02 08:08:45.000000000 +0200 @@ -0,0 +1,28 @@ +// REQUIRED_ARGS: -os=windows +// EXTRA_SOURCES: imports/test24511_c.c +// DISABLED: osx +// This is disabled on macOS because ld complains about _main being undefined +// when clang attempts to preprocess the C file. + +import test24511_c; + +static assert(__traits(getLinkage, CFunctionPointer) == "C"); +static assert(__traits(getLinkage, StdCallFunctionPointer) == "Windows"); +static assert(__traits(getLinkage, cFunction) == "C"); +static assert(__traits(getLinkage, stdcallFunction) == "Windows"); + +static assert(__traits(getLinkage, takesCFunctionPointer) == "Windows"); +static if (is(typeof(&takesCFunctionPointer) ParamsA == __parameters)) + static assert(__traits(getLinkage, ParamsA[0]) == "C"); + +static assert(__traits(getLinkage, takesStdCallFunctionPointer) == "C"); +static if (is(typeof(&takesStdCallFunctionPointer) ParamsB == __parameters)) + static assert(__traits(getLinkage, ParamsB[0]) == "Windows"); + +static assert(__traits(getLinkage, StdCallFunctionPointerTakingCFunctionPointer) == "Windows"); +static if (is(typeof(&StdCallFunctionPointerTakingCFunctionPointer) ParamsC == __parameters)) + static assert(__traits(getLinkage, ParamsC[0]) == "C"); + +static assert(__traits(getLinkage, CFunctionPointerTakingStdCallFunctionPointer) == "C"); +static if (is(typeof(&CFunctionPointerTakingStdCallFunctionPointer) ParamsD == __parameters)) + static assert(__traits(getLinkage, ParamsD[0]) == "Windows"); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dmd-2.108.0/compiler/test/runnable/imports/issue18919b.d new/dmd-2.108.1/compiler/test/runnable/imports/issue18919b.d --- old/dmd-2.108.0/compiler/test/runnable/imports/issue18919b.d 2024-04-01 20:40:58.000000000 +0200 +++ new/dmd-2.108.1/compiler/test/runnable/imports/issue18919b.d 2024-05-02 08:08:45.000000000 +0200 @@ -248,3 +248,9 @@ printf(" %s", arg); printf("\n"); } + +// https://issues.dlang.org/show_bug.cgi?id=24519 +void func13(string file = __FILE__[]) +{ + printf("%s: %s\n", __FUNCTION__.ptr, file.ptr); +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dmd-2.108.0/compiler/test/runnable/issue18919.d new/dmd-2.108.1/compiler/test/runnable/issue18919.d --- old/dmd-2.108.0/compiler/test/runnable/issue18919.d 2024-04-01 20:40:58.000000000 +0200 +++ new/dmd-2.108.1/compiler/test/runnable/issue18919.d 2024-05-02 08:08:45.000000000 +0200 @@ -20,10 +20,13 @@ imports.issue18919b.func10: expr1=imports.issue18919b, expr2=imports.issue18919b imports.issue18919b.func11: issue18919b.d:233 imports.issue18919b imports.issue18919b.func12: issue18919.d issue18919.main void issue18919.main() issue18919 +imports.issue18919b.func13: runnable/issue18919.d --- */ import imports.issue18919b; +#line 26 + void main() { func1(); @@ -44,4 +47,5 @@ func10(); func11(); func12(); + func13(); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dmd-2.108.0/compiler/test/runnable/structinit.c new/dmd-2.108.1/compiler/test/runnable/structinit.c --- old/dmd-2.108.0/compiler/test/runnable/structinit.c 1970-01-01 01:00:00.000000000 +0100 +++ new/dmd-2.108.1/compiler/test/runnable/structinit.c 2024-05-02 08:08:45.000000000 +0200 @@ -0,0 +1,217 @@ +// https://issues.dlang.org/show_bug.cgi?id=24031 + +#include <assert.h> + +/**************************************/ + +struct ES { + struct { + char data[24]; + }; + int length; +}; + +struct ES empty = {.data = {1}, .length = 2}; + +void test1() +{ + assert(empty.data[0] == 1); + assert(empty.length == 2); +} + +/**************************************/ + +struct SH { + int k; + struct { + struct { + struct { + int s; + } f; + }; + }; +}; + +struct SH data = (struct SH) { + .k = 1, + {{.f = {.s = 2}}} +}; + +void test2() +{ + assert(data.k == 1); + assert(data.f.s == 2); +} + +/**************************************/ + +// https://issues.dlang.org/show_bug.cgi?id=24266 + +struct S3 +{ + int context[4]; + int id; +}; + +void test3() +{ + struct S3 tn = (struct S3) {{1}, 4}; + assert(tn.context[0] == 1); + assert(tn.context[1] == 0); + assert(tn.context[2] == 0); + assert(tn.context[3] == 0); + assert(tn.id == 4); +} + +/**************************************/ +// https://issues.dlang.org/show_bug.cgi?id=24274 + +struct S0 +{ + struct + { + char short_data[24]; + }; + int length; +}; + +void test4() +{ + struct S0 s0 = { {.short_data = {1}}, .length = 2}; + assert(s0.short_data[0] == 1); + assert(s0.length == 2); +} + +/**************************************/ + +struct S1 +{ + struct + { + int long_data; + char short_data[24]; + }; + int length; +}; + +void test5() +{ + struct S1 s1 = { {.short_data = {7}}, .length = 8}; + assert(s1.long_data == 0); + assert(s1.short_data[0] == 7); + assert(s1.length == 8); +} + +/**************************************/ + +struct S6 +{ + int abc[4]; +}; + +void test6() +{ + struct S6 s = {{4},5,6,7}; + assert(s.abc[0] == 4); + assert(s.abc[1] == 0); + assert(s.abc[2] == 0); + assert(s.abc[3] == 0); + + struct S6 t = {4,{5},6,7}; + assert(t.abc[0] == 4); + assert(t.abc[1] == 5); + assert(t.abc[2] == 6); + assert(t.abc[3] == 7); +} + +/**************************************/ +// https://issues.dlang.org/show_bug.cgi?id=24495 +struct Subitem { + int x; + int y; +}; + +struct Item { + + int a; + + struct { + int b1; + struct Subitem b2; + int b3; + }; + +}; + +void test7() { + + struct Item first = { + .a = 1, + .b1 = 2, + .b3 = 3, + }; + struct Item second = { + .a = 1, + { + .b1 = 2, + .b2 = { 1, 2 }, + .b3 = 3 + } + }; + + assert(second.a == 1); + assert(second.b1 == 2); + assert(second.b2.x == 1); + assert(second.b2.y == 2); + assert(second.b3 == 3); +} + + +/**************************************/ +// https://issues.dlang.org/show_bug.cgi?id=24277 +struct S8 +{ + int s; + struct + { + int vis; + int count; + int id; + struct + { + int symbol; + int state; + } leaf; + }; +}; + +struct S8 s8 = (struct S8) { + .s = 10, + { + .count = 20, + .id = 30, + .leaf = {.symbol = 40, .state = 50}, + } +}; + +void test8() +{ + assert(s8.id == 30); + assert(s8.leaf.symbol == 40); + assert(s8.leaf.state == 50); +} + +/**************************************/ + +int main() +{ + test1(); + test2(); + test3(); + test4(); + test5(); + test6(); + test7(); + test8(); + return 0; +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dmd-2.108.0/compiler/test/runnable/test24042.c new/dmd-2.108.1/compiler/test/runnable/test24042.c --- old/dmd-2.108.0/compiler/test/runnable/test24042.c 2024-04-01 20:40:58.000000000 +0200 +++ new/dmd-2.108.1/compiler/test/runnable/test24042.c 1970-01-01 01:00:00.000000000 +0100 @@ -1,138 +0,0 @@ -// https://issues.dlang.org/show_bug.cgi?id=24031 - -#include <assert.h> - -/**************************************/ - -struct ES { - struct { - char data[24]; - }; - int length; -}; - -struct ES empty = {.data = {1}, .length = 2}; - -void test1() -{ - assert(empty.data[0] == 1); - assert(empty.length == 2); -} - -/**************************************/ - -struct SH { - int k; - struct { - struct { - struct { - int s; - } f; - }; - }; -}; - -struct SH data = (struct SH) { - .k = 1, - {{.f = {.s = 2}}} -}; - -void test2() -{ - assert(data.k == 1); - assert(data.f.s == 2); -} - -/**************************************/ - -// https://issues.dlang.org/show_bug.cgi?id=24266 - -struct S3 -{ - int context[4]; - int id; -}; - -void test3() -{ - struct S3 tn = (struct S3) {{1}, 4}; - assert(tn.context[0] == 1); - assert(tn.context[1] == 0); - assert(tn.context[2] == 0); - assert(tn.context[3] == 0); - assert(tn.id == 4); -} - -/**************************************/ -// https://issues.dlang.org/show_bug.cgi?id=24274 - -struct S0 -{ - struct - { - char short_data[24]; - }; - int length; -}; - -void test4() -{ - struct S0 s0 = { {.short_data = {1}}, .length = 2}; - assert(s0.short_data[0] == 1); - assert(s0.length == 2); -} - -/**************************************/ - -struct S1 -{ - struct - { - int long_data; - char short_data[24]; - }; - int length; -}; - -void test5() -{ - struct S1 s1 = { {.short_data = {7}}, .length = 8}; - assert(s1.long_data == 0); - assert(s1.short_data[0] == 7); - assert(s1.length == 8); -} - -/**************************************/ - -struct S6 -{ - int abc[4]; -}; - -void test6() -{ - struct S6 s = {{4},5,6,7}; - assert(s.abc[0] == 4); - assert(s.abc[1] == 0); - assert(s.abc[2] == 0); - assert(s.abc[3] == 0); - - struct S6 t = {4,{5},6,7}; - assert(t.abc[0] == 4); - assert(t.abc[1] == 5); - assert(t.abc[2] == 6); - assert(t.abc[3] == 7); -} - -/**************************************/ - -int main() -{ - test1(); - test2(); - test3(); - test4(); - test5(); - test6(); - return 0; -} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dmd-2.108.0/compiler/test/runnable/test24498.d new/dmd-2.108.1/compiler/test/runnable/test24498.d --- old/dmd-2.108.0/compiler/test/runnable/test24498.d 1970-01-01 01:00:00.000000000 +0100 +++ new/dmd-2.108.1/compiler/test/runnable/test24498.d 2024-05-02 08:08:45.000000000 +0200 @@ -0,0 +1,21 @@ +import core.memory; + +void main() +{ + { + int[][] a = new int[][](2, 2); + assert(!(GC.getAttr(a.ptr) & GC.BlkAttr.NO_SCAN)); + assert(GC.getAttr(a[0].ptr) & GC.BlkAttr.NO_SCAN); + } + { + void*[][] a = new void*[][](2, 2); + assert(!(GC.getAttr(a.ptr) & GC.BlkAttr.NO_SCAN)); + assert(!(GC.getAttr(a[0].ptr) & GC.BlkAttr.NO_SCAN)); + } + { + int[][][] a = new int[][][](2, 2); + assert(!(GC.getAttr(a.ptr) & GC.BlkAttr.NO_SCAN)); + assert(!(GC.getAttr(a[0].ptr) & GC.BlkAttr.NO_SCAN)); + assert(a[0][0].ptr is null); + } +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dmd-2.108.0/druntime/src/core/internal/array/construction.d new/dmd-2.108.1/druntime/src/core/internal/array/construction.d --- old/dmd-2.108.0/druntime/src/core/internal/array/construction.d 2024-04-01 20:40:58.000000000 +0200 +++ new/dmd-2.108.1/druntime/src/core/internal/array/construction.d 2024-05-02 08:08:45.000000000 +0200 @@ -526,7 +526,7 @@ auto dim = dims[0]; - debug(PRINTF) printf("__allocateInnerArray(ti = %p, ti.next = %p, dim = %d, ndims = %d\n", ti, ti.next, dim, dims.length); + debug(PRINTF) printf("__allocateInnerArray(UnqT = %s, dim = %lu, ndims = %lu\n", UnqT.stringof.ptr, dim, dims.length); if (dims.length == 1) { auto r = _d_newarrayT!UnqT(dim, isShared); @@ -534,8 +534,9 @@ } auto allocSize = (void[]).sizeof * dim; - auto info = __arrayAlloc!UnqT(allocSize); - __setArrayAllocLength!UnqT(info, allocSize, isShared); + // the array-of-arrays holds pointers! Don't use UnqT here! + auto info = __arrayAlloc!(void[])(allocSize); + __setArrayAllocLength!(void[])(info, allocSize, isShared); auto p = __arrayStart(info)[0 .. dim]; foreach (i; 0..dim) @@ -579,6 +580,16 @@ } } +// https://issues.dlang.org/show_bug.cgi?id=24436 +@system unittest +{ + import core.memory : GC; + + int[][] a = _d_newarraymTX!(int[][], int)([2, 2]); + + assert(!(GC.getAttr(a.ptr) & GC.BlkAttr.NO_SCAN)); +} + version (D_ProfileGC) { /** diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dmd-2.108.0/druntime/src/importc.h new/dmd-2.108.1/druntime/src/importc.h --- old/dmd-2.108.0/druntime/src/importc.h 2024-04-01 20:40:58.000000000 +0200 +++ new/dmd-2.108.1/druntime/src/importc.h 2024-05-02 08:08:45.000000000 +0200 @@ -134,6 +134,7 @@ #define __ptr64 #define __unaligned #define _NO_CRT_STDIO_INLINE 1 +#define _stdcall __stdcall // This header disables the Windows API Annotations macros // Need to include sal.h to get the pragma once to prevent macro redefinition. ++++++ phobos-2.108.0.tar.gz -> phobos-2.108.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/phobos-2.108.0/.dscanner.ini new/phobos-2.108.1/.dscanner.ini --- old/phobos-2.108.0/.dscanner.ini 2024-04-01 20:15:25.000000000 +0200 +++ new/phobos-2.108.1/.dscanner.ini 2024-05-02 01:54:11.000000000 +0200 @@ -52,7 +52,7 @@ ; Checks for local imports that are too broad local_import_check="skip-unittest" ; Checks for variables that could be declared immutable -could_be_immutable_check="enabled" +could_be_immutable_check="skip-unittest" ; Checks for redundant expressions in if statements redundant_if_check="enabled" ; Checks for redundant parenthesis diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/phobos-2.108.0/changelog/range_predicate_element.dd new/phobos-2.108.1/changelog/range_predicate_element.dd --- old/phobos-2.108.0/changelog/range_predicate_element.dd 2024-04-01 20:15:25.000000000 +0200 +++ new/phobos-2.108.1/changelog/range_predicate_element.dd 1970-01-01 01:00:00.000000000 +0100 @@ -1,24 +0,0 @@ -`isForwardRange`, `isBidirectionalRange`, and `isRandomAccessRange` now take an optional element type - -In Phobos 2.106, an optional second template parameter was added to -`isInputRange` to enable conveniently checking a range's element type. Now, the -same parameter has been added to `isForwardRange`, `isBidirectionalRange`, and -`isRandomAccessRange`. - -As before, if a second type argument is passed to one of these templates, the -range's element type is checked to see if it is -$(DDSUBLINK spec/const3, implicit_qualifier_conversions, qualifier-convertible) -to the given type, and this additional check must pass in order for the -template to evaluate to `true`. - -Examples: ---- -// exact match -static assert( isForwardRange!(int[], int)); - -// match with qualifier conversion -static assert( isBidirectionalRange!(int[], const(int)); - -// not a match -static assert(!isRandomAccessRange!(int[], string)); ---- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/phobos-2.108.0/changelog/upgrade-unicode.dd new/phobos-2.108.1/changelog/upgrade-unicode.dd --- old/phobos-2.108.0/changelog/upgrade-unicode.dd 2024-04-01 20:15:25.000000000 +0200 +++ new/phobos-2.108.1/changelog/upgrade-unicode.dd 1970-01-01 01:00:00.000000000 +0100 @@ -1,20 +0,0 @@ -std.uni has been upgraded from Unicode 15.0.0 to 15.1.0 - -This Unicode update was released September 12, 2023. -See: https://www.unicode.org/versions/Unicode15.1.0/ - -``` -import std; - -void main() -{ - const alphaCount = iota(0, dchar.max).filter!(std.uni.isAlpha).walkLength; - writeln(alphaCount); - // formerly: 137765 - // now: 138387 - // 622 new dchars return true for `isAlpha` -} -``` - -The internal unicode tables (std/internal/unicode_tables.d) have also been changed to use hex strings instead of array literals, which makes them faster to import. -The exact speed up depends on your computer and D compiler, but it likely cuts between 30 and 100 milliseconds if you compile something which imports `std.string` or `std.uni`. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/phobos-2.108.0/std/internal/test/range.d new/phobos-2.108.1/std/internal/test/range.d --- old/phobos-2.108.0/std/internal/test/range.d 2024-04-01 20:15:25.000000000 +0200 +++ new/phobos-2.108.1/std/internal/test/range.d 2024-05-02 01:54:11.000000000 +0200 @@ -23,3 +23,94 @@ auto r = R().chunks(3); assert(r.equal!equal([[ 0, 1, 2 ], [ 3, 4 ]])); } + +// https://issues.dlang.org/show_bug.cgi?id=24415 +@safe unittest +{ + import std.range : only; + + static struct S(T) + { + T i; + + this(ref return scope inout(S) rhs) scope @safe inout pure nothrow + { + i = rhs.i; + } + } + { + auto a = only(S!int(42)); + auto b = a; + assert(!b.empty); + assert(b.front == S!int(42)); + + a.popFront(); + auto c = a; + assert(c.empty); + } + { + auto a = only(S!(const int)(42)); + auto b = a; + assert(!b.empty); + assert(b.front == S!(const int)(42)); + + a.popFront(); + auto c = a; + assert(c.empty); + } + { + auto a = only(S!(immutable int)(42)); + auto b = a; + assert(!b.empty); + assert(b.front == S!(immutable int)(42)); + + a.popFront(); + auto c = a; + assert(c.empty); + } + { + auto a = only(S!int(42), S!int(192)); + auto b = a; + assert(!b.empty); + assert(b.front == S!int(42)); + + a.popFront(); + auto c = a; + assert(!c.empty); + assert(c.front == S!int(192)); + + a.popFront(); + auto d = a; + assert(d.empty); + } + { + auto a = only(S!(const int)(42), S!(const int)(192)); + auto b = a; + assert(!b.empty); + assert(b.front == S!(const int)(42)); + + a.popFront(); + auto c = a; + assert(!c.empty); + assert(c.front == S!(const int)(192)); + + a.popFront(); + auto d = a; + assert(d.empty); + } + { + auto a = only(S!(immutable int)(42), S!(immutable int)(192)); + auto b = a; + assert(!b.empty); + assert(b.front == S!(immutable int)(42)); + + a.popFront(); + auto c = a; + assert(!c.empty); + assert(c.front == S!(immutable int)(192)); + + a.popFront(); + auto d = a; + assert(d.empty); + } +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/phobos-2.108.0/std/logger/core.d new/phobos-2.108.1/std/logger/core.d --- old/phobos-2.108.0/std/logger/core.d 2024-04-01 20:15:25.000000000 +0200 +++ new/phobos-2.108.1/std/logger/core.d 2024-05-02 01:54:11.000000000 +0200 @@ -1473,15 +1473,15 @@ atomicStore!(MemoryOrder.seq)(stdSharedLogger, atomicLoad(logger)); } -/** This methods get and set the global `LogLevel`. +/** These methods get and set the global `LogLevel`. -Every log message with a `LogLevel` lower as the global `LogLevel` +Every log message with a `LogLevel` lower than the global `LogLevel` will be discarded before it reaches `writeLogMessage` method of any `Logger`. */ /* Implementation note: For any public logging call, the global log level shall only be queried once on -entry. Otherwise when another threads changes the level, we would work with +entry. Otherwise when another thread changes the level, we would work with different levels at different spots in the code. */ @property LogLevel globalLogLevel() @safe @nogc diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/phobos-2.108.0/std/range/package.d new/phobos-2.108.1/std/range/package.d --- old/phobos-2.108.0/std/range/package.d 2024-04-01 20:15:25.000000000 +0200 +++ new/phobos-2.108.1/std/range/package.d 2024-05-02 01:54:11.000000000 +0200 @@ -313,16 +313,18 @@ { @property void front(ElementType!R val) { - import std.algorithm.mutation : move; + import core.lifetime : forward; - source.back = move(val); + // __ctfe check is workaround for https://issues.dlang.org/show_bug.cgi?id=21542 + source.back = __ctfe ? val : forward!val; } @property void back(ElementType!R val) { - import std.algorithm.mutation : move; + import core.lifetime : forward; - source.front = move(val); + // __ctfe check is workaround for https://issues.dlang.org/show_bug.cgi?id=21542 + source.front = __ctfe ? val : forward!val; } } @@ -334,9 +336,10 @@ { void opIndexAssign(ElementType!R val, size_t n) { - import std.algorithm.mutation : move; + import core.lifetime : forward; - source[retroIndex(n)] = move(val); + // __ctfe check is workaround for https://issues.dlang.org/show_bug.cgi?id=21542 + source[retroIndex(n)] = __ctfe ? val : forward!val; } } @@ -494,6 +497,32 @@ assert(equal(r, [S(3), S(2), S(1)])); } +// https://issues.dlang.org/show_bug.cgi?id=24481 +@safe unittest +{ + bool called; + struct Handle + { + int entry; + void opAssign()(auto ref const(typeof(this)) that) const { called = true; } + } + + const(Handle)[5] arr = [Handle(0), Handle(1), Handle(2), Handle(3), Handle(4)]; + auto range = arr[].retro(); + + called = false; + range.front = Handle(42); + assert(called); + + called = false; + range.back = Handle(42); + assert(called); + + called = false; + range[2] = Handle(42); + assert(called); +} + /** Iterates range `r` with stride `n`. If the range is a random-access range, moves by indexing into the range; otherwise, @@ -604,9 +633,10 @@ { @property void front(ElementType!R val) { - import std.algorithm.mutation : move; + import core.lifetime : forward; - source.front = move(val); + // __ctfe check is workaround for https://issues.dlang.org/show_bug.cgi?id=21542 + source.front = __ctfe ? val : forward!val; } } @@ -899,6 +929,24 @@ assert(equal(r, [S(1), S(4)])); } +// https://issues.dlang.org/show_bug.cgi?id=24481 +@safe unittest +{ + bool called; + struct Handle + { + int entry; + void opAssign()(auto ref const(typeof(this)) that) const { called = true; } + } + + const(Handle)[5] arr = [Handle(0), Handle(1), Handle(2), Handle(3), Handle(4)]; + auto range = arr[].stride(2); + + called = false; + range.front = Handle(42); + assert(called); +} + /** Spans multiple ranges in sequence. The function `chain` takes any number of ranges and returns a $(D Chain!(R1, R2,...)) object. The @@ -1120,14 +1168,15 @@ @property void front(RvalueElementType v) { - import std.algorithm.mutation : move; + import core.lifetime : forward; sw: switch (frontIndex) { static foreach (i; 0 .. R.length) { case i: - source[i].front = move(v); + // __ctfe check is workaround for https://issues.dlang.org/show_bug.cgi?id=21542 + source[i].front = __ctfe ? v : forward!v; break sw; } @@ -1246,14 +1295,15 @@ { @property void back(RvalueElementType v) { - import std.algorithm.mutation : move; + import core.lifetime : forward; sw: switch (backIndex) { static foreach_reverse (i; 1 .. R.length + 1) { case i: - source[i-1].back = move(v); + // __ctfe check is workaround for https://issues.dlang.org/show_bug.cgi?id=21542 + source[i - 1].back = __ctfe ? v : forward!v; break sw; } @@ -1359,7 +1409,7 @@ static if (allSameType && allSatisfy!(hasAssignableElements, R)) void opIndexAssign(ElementType v, size_t index) { - import std.algorithm.mutation : move; + import core.lifetime : forward; sw: switch (frontIndex) { @@ -1376,7 +1426,8 @@ } } - source[i][index] = move(v); + // __ctfe check is workaround for https://issues.dlang.org/show_bug.cgi?id=21542 + source[i][index] = __ctfe ? v : forward!v; break sw; } @@ -1727,6 +1778,32 @@ assert(typeof(range).init.empty); } +// https://issues.dlang.org/show_bug.cgi?id=24481 +@safe unittest +{ + bool called; + struct Handle + { + int entry; + void opAssign()(auto ref const(typeof(this)) that) const { called = true; } + } + + const(Handle)[5] arr = [Handle(0), Handle(1), Handle(2), Handle(3), Handle(4)]; + auto range = arr[0 .. 2].chain(arr[4 .. 5]); + + called = false; + range.front = Handle(42); + assert(called); + + called = false; + range.back = Handle(42); + assert(called); + + called = false; + range[2] = Handle(42); + assert(called); +} + /** Choose one of two ranges at runtime depending on a Boolean condition. @@ -2694,12 +2771,14 @@ /// ditto @property void front(ElementType!R v) { - import std.algorithm.mutation : move; + import core.lifetime : forward; assert(!empty, "Attempting to assign to the front of an empty " ~ Take.stringof); - source.front = move(v); + + // __ctfe check is workaround for https://issues.dlang.org/show_bug.cgi?id=21542 + source.front = __ctfe ? v : forward!v; } static if (hasMobileElements!R) @@ -2996,6 +3075,25 @@ assert(r.take(2).equal(repeat(1, 2))); } +// https://issues.dlang.org/show_bug.cgi?id=24481 +@safe unittest +{ + import std.algorithm.iteration : filter; + + bool called; + struct Handle + { + int entry; + void opAssign()(auto ref const(typeof(this)) that) const { called = true; } + } + + const(Handle)[5] arr = [Handle(0), Handle(1), Handle(2), Handle(3), Handle(4)]; + auto range = arr[].filter!(a => true)().take(3); + + called = false; + range.front = Handle(42); + assert(called); +} /** Similar to $(LREF take), but assumes that `range` has at least $(D @@ -3075,12 +3173,14 @@ { @property auto ref front(ElementType!R v) { - import std.algorithm.mutation : move; + import core.lifetime : forward; assert(!empty, "Attempting to assign to the front of an empty " ~ typeof(this).stringof); - return _input.front = move(v); + + // __ctfe check is workaround for https://issues.dlang.org/show_bug.cgi?id=21542 + return _input.front = __ctfe ? v : forward!v; } } } @@ -3217,6 +3317,26 @@ }} } +// https://issues.dlang.org/show_bug.cgi?id=24481 +@safe unittest +{ + import std.algorithm.iteration : filter; + + bool called; + struct Handle + { + int entry; + void opAssign()(auto ref const(typeof(this)) that) const { called = true; } + } + + const(Handle)[5] arr = [Handle(0), Handle(1), Handle(2), Handle(3), Handle(4)]; + auto range = arr[].filter!(a => true)().takeExactly(3); + + called = false; + range.front = Handle(42); + assert(called); +} + /** Returns a range with at most one element; for example, $(D takeOne([42, 43, 44])) returns a range consisting of the integer $(D @@ -4310,9 +4430,10 @@ /// ditto @property void front(ElementType!R val) { - import std.algorithm.mutation : move; + import core.lifetime : forward; - _original[_index] = move(val); + // __ctfe check is workaround for https://issues.dlang.org/show_bug.cgi?id=21542 + _original[_index] = __ctfe ? val : forward!val; } } @@ -4422,9 +4543,10 @@ /// ditto @property auto front(ElementType!R val) { - import std.algorithm.mutation : move; + import core.lifetime : forward; - return _current.front = move(val); + // __ctfe check is workaround for https://issues.dlang.org/show_bug.cgi?id=21542 + return _current.front = __ctfe ? val : forward!val; } } @@ -4767,6 +4889,35 @@ assert(equal(r.save, "foof")); } +// https://issues.dlang.org/show_bug.cgi?id=24481 +@safe unittest +{ + import std.algorithm.iteration : filter; + + bool called; + struct Handle + { + int entry; + void opAssign()(auto ref const(typeof(this)) that) const { called = true; } + } + + const(Handle)[3] arr = [Handle(0), Handle(1), Handle(2)]; + { + auto range = arr[].cycle().take(5); + + called = false; + range.front = Handle(42); + assert(called); + } + { + auto range = arr[].filter!(a => true)().cycle().take(5); + + called = false; + range.front = Handle(42); + assert(called); + } +} + private alias lengthType(R) = typeof(R.init.length.init); /** @@ -7438,9 +7589,10 @@ { @property void front(ElementType val) { - import std.algorithm.mutation : move; + import core.lifetime : forward; - _input.front.front = move(val); + // __ctfe check is workaround for https://issues.dlang.org/show_bug.cgi?id=21542 + _input.front.front = __ctfe ? val : forward!val; } } @@ -7497,9 +7649,10 @@ { @property void back(ElementType val) { - import std.algorithm.mutation : move; + import core.lifetime : forward; - _input.back.front = move(val); + // __ctfe check is workaround for https://issues.dlang.org/show_bug.cgi?id=21542 + _input.back.front = __ctfe ? val : forward!val; } } } @@ -7532,9 +7685,10 @@ { void opIndexAssign(ElementType val, size_t n) { - import std.algorithm.mutation : move; + import core.lifetime : forward; - _input[n].front = move(val); + // __ctfe check is workaround for https://issues.dlang.org/show_bug.cgi?id=21542 + _input[n].front = __ctfe ? val : forward!val; } } mixin ImplementLength!_input; @@ -7675,6 +7829,50 @@ assert(ft.empty); } +// https://issues.dlang.org/show_bug.cgi?id=24481 +@safe unittest +{ + bool called; + struct Handle + { + int entry; + void opAssign()(auto ref const(typeof(this)) that) const { called = true; } + } + + const(Handle)[][] arr = [[Handle(0), Handle(10)], + [Handle(1), Handle(11)], + [Handle(2), Handle(12)], + [Handle(3), Handle(13)], + [Handle(4), Handle(14)]]; + + { + auto range = arr.frontTransversal(); + + called = false; + range.front = Handle(42); + assert(called == true); + + called = false; + range.back = Handle(42); + assert(called == true); + } + { + auto range = arr.frontTransversal!(TransverseOptions.assumeNotJagged)(); + + called = false; + range.front = Handle(42); + assert(called == true); + + called = false; + range.back = Handle(42); + assert(called == true); + + called = false; + range[0] = Handle(42); + assert(called == true); + } +} + /** Given a range of ranges, iterate transversally through the `n`th element of each of the enclosed ranges. This function @@ -10375,6 +10573,14 @@ } alias opDollar = length; + // FIXME Workaround for https://issues.dlang.org/show_bug.cgi?id=24415 + import std.traits : hasElaborateCopyConstructor; + static if (hasElaborateCopyConstructor!T) + { + private static struct WorkaroundBugzilla24415 {} + public this()(WorkaroundBugzilla24415) {} + } + private this()(return scope auto ref T value) { ref @trusted unqual(ref T x){return cast() x;}