From patchwork Fri Mar 17 04:52:56 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Iain Buclaw X-Patchwork-Id: 66495 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 66ADC3854801 for ; Fri, 17 Mar 2023 04:53:37 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 66ADC3854801 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1679028817; bh=mGom9jl8lKpuVownsnqKLsre4rZMtNf2FiWC88g9hO4=; h=To:Cc:Subject:Date:List-Id:List-Unsubscribe:List-Archive: List-Post:List-Help:List-Subscribe:From:Reply-To:From; b=HQgVghx68sDComjpaRj//4ThfNMKkxvFXzoCcXWaAvi5QfAInK9NKCQvqKhu1B+F+ Pn/jcjrWlC44wkZ8tSwSc8uPGddd2FbTGMZccA47aJ1OKHQLE+FwHfA+WTaC+CoZju 5OVD05JIRS9d1+IbL5pX9mjvOujfPjVviCgMG6pI= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mout-p-101.mailbox.org (mout-p-101.mailbox.org [IPv6:2001:67c:2050:0:465::101]) by sourceware.org (Postfix) with ESMTPS id 4F5833858423 for ; Fri, 17 Mar 2023 04:53:05 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 4F5833858423 Received: from smtp202.mailbox.org (smtp202.mailbox.org [IPv6:2001:67c:2050:b231:465::202]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-384) server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by mout-p-101.mailbox.org (Postfix) with ESMTPS id 4PdBb158cSz9swd; Fri, 17 Mar 2023 05:53:01 +0100 (CET) To: gcc-patches@gcc.gnu.org Cc: Iain Buclaw Subject: [committed] d: Merge upstream dmd, druntime 5f7552bb28, phobos 67a47cf39. Date: Fri, 17 Mar 2023 05:52:56 +0100 Message-Id: <20230317045256.34563-1-ibuclaw@gdcproject.org> MIME-Version: 1.0 X-Rspamd-Queue-Id: 4PdBb158cSz9swd X-Spam-Status: No, score=-13.3 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_LOTSOFHASH, RCVD_IN_DNSWL_LOW, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Iain Buclaw via Gcc-patches From: Iain Buclaw Reply-To: Iain Buclaw Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" Hi, This patch merges the D front-end and run-time library with upstream dmd 5f7552bb28, and standard library with phobos 67a47cf39. Synchronizing the latest bug fixes in the upcoming v2.103.0 release. D front-end changes: - Import dmd v2.103.0-rc.1. D runtime changes: - Import druntime v2.103.0-rc.1. Phobos changes: - Import phobos v2.103.0-rc.1. gcc/d/ChangeLog: * dmd/MERGE: Merge upstream dmd 5f7552bb28. * dmd/VERSION: Bump version to v2.103.0-rc.1. Bootstrapped and regression tested on x86_64-linux-gnu/-m32/-mx32, committed to mainline. Regards, Iain. --- libphobos/ChangeLog: * libdruntime/MERGE: Merge upstream druntime 5f7552bb28. * src/MERGE: Merge upstream phobos 67a47cf39. --- gcc/d/dmd/MERGE | 2 +- gcc/d/dmd/VERSION | 2 +- gcc/d/dmd/dinterpret.d | 12 ++- gcc/d/dmd/dsymbol.d | 21 +++- gcc/d/dmd/expressionsem.d | 102 +++++++++++++++++- gcc/d/dmd/typesem.d | 1 + gcc/d/dmd/typinf.d | 5 +- gcc/testsuite/gdc.test/compilable/test16213.d | 8 ++ gcc/testsuite/gdc.test/compilable/test17351.d | 9 ++ gcc/testsuite/gdc.test/compilable/test19295.d | 10 ++ .../gdc.test/compilable/testcorrectthis.d | 37 +++++++ .../gdc.test/fail_compilation/fail23760.d | 27 +++++ .../gdc.test/fail_compilation/fail61.d | 2 +- .../gdc.test/fail_compilation/fail_circular.d | 15 +-- .../gdc.test/fail_compilation/ice19295.d | 18 ---- .../gdc.test/fail_compilation/ice23781.d | 10 ++ .../gdc.test/fail_compilation/ice9439.d | 4 +- libphobos/libdruntime/MERGE | 2 +- libphobos/src/MERGE | 2 +- libphobos/src/std/math/exponential.d | 30 ++++-- libphobos/src/std/traits.d | 27 ++++- 21 files changed, 295 insertions(+), 51 deletions(-) create mode 100644 gcc/testsuite/gdc.test/compilable/test16213.d create mode 100644 gcc/testsuite/gdc.test/compilable/test19295.d create mode 100644 gcc/testsuite/gdc.test/compilable/testcorrectthis.d create mode 100644 gcc/testsuite/gdc.test/fail_compilation/fail23760.d delete mode 100644 gcc/testsuite/gdc.test/fail_compilation/ice19295.d create mode 100644 gcc/testsuite/gdc.test/fail_compilation/ice23781.d diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE index 269eebfc483..986925e8bdc 100644 --- a/gcc/d/dmd/MERGE +++ b/gcc/d/dmd/MERGE @@ -1,4 +1,4 @@ -4ca4140e584c055a8a9bc727e56a97ebcecd61e0 +5f7552bb2829b75d5e36cc767a476e1ab35147b7 The first line of this file holds the git revision number of the last merge done from the dlang/dmd repository. diff --git a/gcc/d/dmd/VERSION b/gcc/d/dmd/VERSION index 8b24f92dab7..da496a2ceeb 100644 --- a/gcc/d/dmd/VERSION +++ b/gcc/d/dmd/VERSION @@ -1 +1 @@ -v2.103.0-beta.1 +v2.103.0-rc.1 diff --git a/gcc/d/dmd/dinterpret.d b/gcc/d/dmd/dinterpret.d index 9073b0db2f8..e6ef704be86 100644 --- a/gcc/d/dmd/dinterpret.d +++ b/gcc/d/dmd/dinterpret.d @@ -2036,7 +2036,7 @@ public: } auto er = interpret(e.e1, istate, CTFEGoal.LValue); if (auto ve = er.isVarExp()) - if (ve.var == istate.fd.vthis) + if (istate && ve.var == istate.fd.vthis) er = interpret(er, istate); if (exceptionOrCant(er)) @@ -2117,6 +2117,16 @@ public: return CTFEExp.cantexp; assert(e.type); + // There's a terrible hack in `dmd.dsymbolsem` that special case + // a struct with all zeros to an `ExpInitializer(BlitExp(IntegerExp(0)))` + // There's matching code for it in e2ir (toElem's visitAssignExp), + // so we need the same hack here. + // This does not trigger for global as they get a normal initializer. + if (auto ts = e.type.isTypeStruct()) + if (auto ae = e.isBlitExp()) + if (ae.e2.op == EXP.int64) + e = ts.defaultInitLiteral(loc); + if (e.op == EXP.construct || e.op == EXP.blit) { AssignExp ae = cast(AssignExp)e; diff --git a/gcc/d/dmd/dsymbol.d b/gcc/d/dmd/dsymbol.d index aa478f2fea2..e7ce93ee067 100644 --- a/gcc/d/dmd/dsymbol.d +++ b/gcc/d/dmd/dsymbol.d @@ -2162,10 +2162,23 @@ extern (C++) final class ArrayScopeSymbol : ScopeDsymbol * or a variable (in which case an expression is created in * toir.c). */ - auto e = new VoidInitializer(Loc.initial); - e.type = Type.tsize_t; - v = new VarDeclaration(loc, Type.tsize_t, Id.dollar, e); - v.storage_class |= STC.temp | STC.ctfe; // it's never a true static variable + + // https://issues.dlang.org/show_bug.cgi?id=16213 + // For static arrays $ is known at compile time, + // so declare it as a manifest constant. + auto tsa = ce.type ? ce.type.isTypeSArray() : null; + if (tsa) + { + auto e = new ExpInitializer(loc, tsa.dim); + v = new VarDeclaration(loc, tsa.dim.type, Id.dollar, e, STC.manifest); + } + else + { + auto e = new VoidInitializer(Loc.initial); + e.type = Type.tsize_t; + v = new VarDeclaration(loc, Type.tsize_t, Id.dollar, e); + v.storage_class |= STC.temp | STC.ctfe; // it's never a true static variable + } } *pvar = v; } diff --git a/gcc/d/dmd/expressionsem.d b/gcc/d/dmd/expressionsem.d index d186abc0552..632ea11cdc0 100644 --- a/gcc/d/dmd/expressionsem.d +++ b/gcc/d/dmd/expressionsem.d @@ -1155,6 +1155,69 @@ L1: return e1; } +/* + * Check whether `outerFunc` and `calledFunc` have the same `this`. + * If `calledFunc` is the member of a base class of the class that contains + * `outerFunc` we consider that they have the same this. + * + * This function is used to test whether `this` needs to be prepended to + * a function call or function symbol. For example: + * + * struct X + * { + * void gun() {} + * } + * struct A + * { + * void fun() {} + * void sun() + * { + * fun(); + * X.gun(); // error + * } + * } + * + * When `fun` is called, `outerfunc` = `sun` and `calledFunc = `fun`. + * `sun` is a member of `A` and `fun` is also a member of `A`, therefore + * `this` can be prepended to `fun`. When `gun` is called (it will result + * in an error, but that is not relevant here), which is a member of `X`, + * no `this` is needed because the outer function does not have the same + * `this` as `gun`. + * + * Returns: + * `true` if outerFunc and calledFunc may use the same `this` pointer. + * `false` otherwise. + */ +private bool haveSameThis(FuncDeclaration outerFunc, FuncDeclaration calledFunc) +{ + auto thisAd = outerFunc.isMemberLocal(); + if (!thisAd) + return false; + + auto requiredAd = calledFunc.isMemberLocal(); + if (!requiredAd) + return false; + + if (thisAd == requiredAd) + return true; + + // outerfunc is the member of a base class that contains calledFunc, + // then we consider that they have the same this. + auto cd = requiredAd.isClassDeclaration(); + if (!cd) + return false; + + if (cd.isBaseOf2(thisAd.isClassDeclaration())) + return true; + + // if outerfunc is the member of a nested aggregate, then let + // getRightThis take care of this. + if (thisAd.isNested()) + return true; + + return false; +} + /*************************************** * Pull out any properties. */ @@ -5209,7 +5272,8 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor if (exp.f.checkNestedReference(sc, exp.loc)) return setError(); - if (hasThis(sc)) + auto memberFunc = hasThis(sc); + if (memberFunc && haveSameThis(memberFunc, exp.f)) { // Supply an implicit 'this', as in // this.ident @@ -6892,8 +6956,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor AggregateDeclaration ad = f.isMemberLocal(); if (f.needThis()) e.e1 = getRightThis(e.loc, sc, ad, e.e1, f); - if (e.e1.op == EXP.error) - return setError(); if (f.type.ty == Tfunction) { @@ -7207,7 +7269,8 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor } if (f.needThis()) { - if (hasThis(sc)) + auto memberFunc = hasThis(sc); + if (memberFunc && haveSameThis(memberFunc, f)) { /* Should probably supply 'this' after overload resolution, * not before. @@ -7309,6 +7372,14 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor goto case Terror; } + if (sc.flags & SCOPE.Cfile && exp.type && exp.type.toBasetype().ty == Tvoid) + { + // https://issues.dlang.org/show_bug.cgi?id=23752 + // `&*((void*)(0))` is allowed in C + result = exp; + return; + } + if (exp.checkValue()) return setError(); @@ -12311,6 +12382,29 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor Type t1 = exp.e1.type; Type t2 = exp.e2.type; + + // https://issues.dlang.org/show_bug.cgi?id=23767 + // `cast(void*) 0` should be treated as `null` so the ternary expression + // gets the pointer type of the other branch + if (sc.flags & SCOPE.Cfile) + { + static void rewriteCNull(ref Expression e, ref Type t) + { + if (!t.isTypePointer()) + return; + if (auto ie = e.optimize(WANTvalue).isIntegerExp()) + { + if (ie.getInteger() == 0) + { + e = new NullExp(e.loc, Type.tnull); + t = Type.tnull; + } + } + } + rewriteCNull(exp.e1, t1); + rewriteCNull(exp.e2, t2); + } + if (t1.ty == Tnoreturn) { exp.type = t2; diff --git a/gcc/d/dmd/typesem.d b/gcc/d/dmd/typesem.d index 84561ac467a..c668199e5f7 100644 --- a/gcc/d/dmd/typesem.d +++ b/gcc/d/dmd/typesem.d @@ -4176,6 +4176,7 @@ Expression dotExp(Type mt, Scope* sc, Expression e, Identifier ident, int flag) } if (v.type.ty == Terror) { + e.error("type of variable `%s` has errors", v.toPrettyChars); return ErrorExp.get(); } diff --git a/gcc/d/dmd/typinf.d b/gcc/d/dmd/typinf.d index 2ca71437d14..38a39b46108 100644 --- a/gcc/d/dmd/typinf.d +++ b/gcc/d/dmd/typinf.d @@ -34,8 +34,9 @@ import core.stdc.stdio; * loc = the location for reporting line numbers in errors * torig = the type to generate the `TypeInfo` object for * sc = the scope + * genObjCode = if true, object code will be generated for the obtained TypeInfo */ -extern (C++) void genTypeInfo(Expression e, const ref Loc loc, Type torig, Scope* sc) +extern (C++) void genTypeInfo(Expression e, const ref Loc loc, Type torig, Scope* sc, bool genObjCode = true) { // printf("genTypeInfo() %s\n", torig.toChars()); @@ -80,7 +81,7 @@ extern (C++) void genTypeInfo(Expression e, const ref Loc loc, Type torig, Scope // generate a COMDAT for other TypeInfos not available as builtins in // druntime - if (!isUnqualifiedClassInfo && !builtinTypeInfo(t)) + if (!isUnqualifiedClassInfo && !builtinTypeInfo(t) && genObjCode) { if (sc) // if in semantic() pass { diff --git a/gcc/testsuite/gdc.test/compilable/test16213.d b/gcc/testsuite/gdc.test/compilable/test16213.d new file mode 100644 index 00000000000..ccf77c6c948 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/test16213.d @@ -0,0 +1,8 @@ +// https://issues.dlang.org/show_bug.cgi?id=16213 + +enum Id(size_t i) = i; +void main() +{ + int[5] y; + y[ Id!($) - 1 ] = 3; +} diff --git a/gcc/testsuite/gdc.test/compilable/test17351.d b/gcc/testsuite/gdc.test/compilable/test17351.d index fffe92c4d58..a04ade12476 100644 --- a/gcc/testsuite/gdc.test/compilable/test17351.d +++ b/gcc/testsuite/gdc.test/compilable/test17351.d @@ -1,3 +1,4 @@ +// PERMUTE_ARGS: -preview=in bool fun(S)(ref S[3] a) { assert(a == [42, 84, 169]); return true; } bool fun2(S)(ref S a) { return true; } void main() @@ -14,4 +15,12 @@ void test2() { static immutable int[2] P = [ 0, 1 ]; static assert(f2(P) == 1); + immutable BigInt a, b; + static assert(glob1.twice == b.twice); + static assert(a.twice == b.twice); } + +struct BigInt { int[64] big; } +BigInt twice (in BigInt v) @safe pure nothrow @nogc { return v; } + +immutable BigInt glob1 = BigInt.init; diff --git a/gcc/testsuite/gdc.test/compilable/test19295.d b/gcc/testsuite/gdc.test/compilable/test19295.d new file mode 100644 index 00000000000..a32a317c08e --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/test19295.d @@ -0,0 +1,10 @@ +struct S1(T...) { + auto fun() { + static assert(__traits(compiles, &T[0])); + } +} + +struct S2 { + void gun() {} + S1!gun overloaded; +} diff --git a/gcc/testsuite/gdc.test/compilable/testcorrectthis.d b/gcc/testsuite/gdc.test/compilable/testcorrectthis.d new file mode 100644 index 00000000000..3adc0628236 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/testcorrectthis.d @@ -0,0 +1,37 @@ +// https://issues.dlang.org/show_bug.cgi?id=10886 + +struct A +{ + @property int foo() { return 0; } + int bar() { return 0; } +} + +struct B +{ + void bar() + { + alias f = typeof(A.foo); // NG + alias b = typeof(A.bar); // ok + } +} + +// https://issues.dlang.org/show_bug.cgi?id=21288 + +struct XA +{ + int p; +} + +struct XB +{ + XA a() { return XA.init; } + alias a this; +} + +struct XC +{ + void foo() + { + static assert(XB.p.stringof == "p"); // Error: this for s needs to be type B not type C + } +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail23760.d b/gcc/testsuite/gdc.test/fail_compilation/fail23760.d new file mode 100644 index 00000000000..fbca6ecd797 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/fail23760.d @@ -0,0 +1,27 @@ +// https://issues.dlang.org/show_bug.cgi?id=23760 + +/* +TEST_OUTPUT: +--- +fail_compilation/fail23760.d(16): Error: type of variable `fail23760.A.state` has errors +fail_compilation/fail23760.d(16): Error: `(A).state` cannot be resolved +fail_compilation/fail23760.d(21): Error: template instance `fail23760.JavaBridge!(A)` error instantiating +fail_compilation/fail23760.d(24): instantiated from here: `JavaClass!(A)` +--- +*/ + +class JavaBridge(Class) +{ + static if(is(typeof(__traits(getMember, Class, "state")))) {} + alias T = __traits(getOverloads, Class, "state"); +} + +class JavaClass(CRTP) +{ + JavaBridge!(CRTP) _javaDBridge; +} + +class A : JavaClass!A +{ + State* state; +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail61.d b/gcc/testsuite/gdc.test/fail_compilation/fail61.d index 90c3b39977d..1386bd664a3 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail61.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail61.d @@ -4,7 +4,7 @@ TEST_OUTPUT: fail_compilation/fail61.d(22): Error: no property `B` for type `fail61.A.B` fail_compilation/fail61.d(23): Error: no property `B` for type `fail61.A.B` fail_compilation/fail61.d(32): Error: no property `A2` for type `fail61.B2` -fail_compilation/fail61.d(41): Error: `this` for `foo` needs to be type `B3` not type `fail61.C3` +fail_compilation/fail61.d(41): Error: need `this` for `foo` of type `void()` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail_circular.d b/gcc/testsuite/gdc.test/fail_compilation/fail_circular.d index 186444e459a..e67fabce91d 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail_circular.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail_circular.d @@ -110,12 +110,15 @@ struct S6 /* TEST_OUTPUT: --- -fail_compilation/fail_circular.d(123): Error: circular reference to variable `fail_circular.C.a1` -fail_compilation/fail_circular.d(125): Error: circular reference to variable `fail_circular.C.b1` -fail_compilation/fail_circular.d(127): Error: circular reference to variable `fail_circular.C.c1` -fail_compilation/fail_circular.d(130): Error: circular reference to variable `fail_circular.C.a1a` -fail_compilation/fail_circular.d(133): Error: circular reference to variable `fail_circular.C.b1a` -fail_compilation/fail_circular.d(136): Error: circular reference to variable `fail_circular.C.c1a` +fail_compilation/fail_circular.d(126): Error: circular reference to variable `fail_circular.C.a1` +fail_compilation/fail_circular.d(128): Error: circular reference to variable `fail_circular.C.b1` +fail_compilation/fail_circular.d(130): Error: circular reference to variable `fail_circular.C.c1` +fail_compilation/fail_circular.d(133): Error: circular reference to variable `fail_circular.C.a1a` +fail_compilation/fail_circular.d(132): Error: type of variable `fail_circular.C.a1b` has errors +fail_compilation/fail_circular.d(136): Error: circular reference to variable `fail_circular.C.b1a` +fail_compilation/fail_circular.d(135): Error: type of variable `fail_circular.C.b1b` has errors +fail_compilation/fail_circular.d(139): Error: circular reference to variable `fail_circular.C.c1a` +fail_compilation/fail_circular.d(138): Error: type of variable `fail_circular.C.c1b` has errors --- */ class C diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice19295.d b/gcc/testsuite/gdc.test/fail_compilation/ice19295.d deleted file mode 100644 index a92f5f8384c..00000000000 --- a/gcc/testsuite/gdc.test/fail_compilation/ice19295.d +++ /dev/null @@ -1,18 +0,0 @@ -/* -TEST_OUTPUT: ---- -fail_compilation/ice19295.d(11): Error: `this` for `gun` needs to be type `S2` not type `S1!(gun)` -fail_compilation/ice19295.d(11): while evaluating `pragma(msg, &gun)` -fail_compilation/ice19295.d(17): Error: template instance `ice19295.S1!(gun)` error instantiating ---- -*/ -struct S1(T...) { - auto fun() { - pragma(msg, &T[0]); - } -} - -struct S2 { - void gun() {} - S1!gun overloaded; -} diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice23781.d b/gcc/testsuite/gdc.test/fail_compilation/ice23781.d new file mode 100644 index 00000000000..7adc11607db --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/ice23781.d @@ -0,0 +1,10 @@ +/** +TEST_OUTPUT: +--- +fail_compilation/ice23781.d(10): Error: variable `b` cannot be read at compile time +--- +**/ +struct Bar { int i; } +ref const(Bar) func1 (const return ref Bar b) { return b; } +immutable E1 = Bar(); +enum E2 = &E1.func1(); diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice9439.d b/gcc/testsuite/gdc.test/fail_compilation/ice9439.d index a9e70083802..5b2a8b12031 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/ice9439.d +++ b/gcc/testsuite/gdc.test/fail_compilation/ice9439.d @@ -1,8 +1,8 @@ /* TEST_OUTPUT: --- -fail_compilation/ice9439.d(12): Error: `this` for `foo` needs to be type `Derived` not type `ice9439.Base` -fail_compilation/ice9439.d(12): while evaluating: `static assert((__error).foo())` +fail_compilation/ice9439.d(12): Error: need `this` for `foo` of type `int()` +fail_compilation/ice9439.d(12): while evaluating: `static assert(foo())` fail_compilation/ice9439.d(19): Error: template instance `ice9439.Base.boo!(foo)` error instantiating --- */ diff --git a/libphobos/libdruntime/MERGE b/libphobos/libdruntime/MERGE index 269eebfc483..986925e8bdc 100644 --- a/libphobos/libdruntime/MERGE +++ b/libphobos/libdruntime/MERGE @@ -1,4 +1,4 @@ -4ca4140e584c055a8a9bc727e56a97ebcecd61e0 +5f7552bb2829b75d5e36cc767a476e1ab35147b7 The first line of this file holds the git revision number of the last merge done from the dlang/dmd repository. diff --git a/libphobos/src/MERGE b/libphobos/src/MERGE index a2191397599..e72db81b710 100644 --- a/libphobos/src/MERGE +++ b/libphobos/src/MERGE @@ -1,4 +1,4 @@ -454dff14dcbd005f9550302c5836ef8e06ab663a +67a47cf39d52b3cb3ae4117c0237415e03737f8a The first line of this file holds the git revision number of the last merge done from the dlang/phobos repository. diff --git a/libphobos/src/std/math/exponential.d b/libphobos/src/std/math/exponential.d index fd1ff244b62..8290479248d 100644 --- a/libphobos/src/std/math/exponential.d +++ b/libphobos/src/std/math/exponential.d @@ -3033,13 +3033,13 @@ private 4.5270000862445199635215E-5, ]; static immutable double[7] logp1Q = [ - 1.0000000000000000000000E0, 6.0118660497603843919306E1, 2.1642788614495947685003E2, 3.0909872225312059774938E2, 2.2176239823732856465394E2, 8.3047565967967209469434E1, 1.5062909083469192043167E1, + 1.0000000000000000000000E0, ]; static immutable double[7] log10P = [ @@ -3101,13 +3101,13 @@ private 4.5270000862E-5, ]; static immutable float[7] logp1Q = [ - 1.00000000000E0, 6.01186604976E1, 2.16427886144E2, 3.09098722253E2, 2.21762398237E2, 8.30475659679E1, 1.50629090834E1, + 1.00000000000E0, ]; // log2 and log10 uses the same coefficients as log. @@ -3323,7 +3323,7 @@ private T logImpl(T, bool LOG1P = false)(T x) @safe pure nothrow @nogc } static foreach (F; AliasSeq!(float, double, real)) {{ - F[2][24] vals = [ + scope F[2][] vals = [ [F(1), F(0x0p+0)], [F(2), F(0x1.62e42fefa39ef358p-1)], [F(4), F(0x1.62e42fefa39ef358p+0)], [F(8), F(0x1.0a2b23f3bab73682p+1)], [F(16), F(0x1.62e42fefa39ef358p+1)], [F(32), F(0x1.bb9d3beb8c86b02ep+1)], @@ -3335,6 +3335,9 @@ private T logImpl(T, bool LOG1P = false)(T x) @safe pure nothrow @nogc [F(17), F(0x1.6aa6bc1fa7f79cfp+1)], [F(31), F(0x1.b78ce48912b59f12p+1)], [F(33), F(0x1.bf8d8f4d5b8d1038p+1)], [F(63), F(0x1.09291e8e3181b20ep+2)], [F(65), F(0x1.0b292939429755ap+2)], [F(-0), -F.infinity], [F(0), -F.infinity], + [F(0.1), F(-0x1.26bb1bbb5551582ep+1)], [F(0.25), F(-0x1.62e42fefa39ef358p+0)], + [F(0.75), F(-0x1.269621134db92784p-2)], [F(0.875), F(-0x1.1178e8227e47bde4p-3)], + [F(10), F(0x1.26bb1bbb5551582ep+1)], [F(100), F(0x1.26bb1bbb5551582ep+2)], [F(10000), F(0x1.26bb1bbb5551582ep+3)], ]; testLog(vals); @@ -3572,7 +3575,7 @@ Ldone: } static foreach (F; AliasSeq!(float, double, real)) {{ - F[2][24] vals = [ + scope F[2][] vals = [ [F(1), F(0x0p+0)], [F(2), F(0x1.34413509f79fef32p-2)], [F(4), F(0x1.34413509f79fef32p-1)], [F(8), F(0x1.ce61cf8ef36fe6cap-1)], [F(16), F(0x1.34413509f79fef32p+0)], [F(32), F(0x1.8151824c7587eafep+0)], @@ -3584,7 +3587,9 @@ Ldone: [F(17), F(0x1.3afeb354b7d9731ap+0)], [F(31), F(0x1.7dc9e145867e62eap+0)], [F(33), F(0x1.84bd545e4baeddp+0)], [F(63), F(0x1.cca1950e4511e192p+0)], [F(65), F(0x1.d01b16f9433cf7b8p+0)], [F(-0), -F.infinity], [F(0), -F.infinity], - [F(10000), F(0x1p+2)], + [F(0.1), F(-0x1p+0)], [F(0.25), F(-0x1.34413509f79fef32p-1)], + [F(0.75), F(-0x1.ffbfc2bbc7803758p-4)], [F(0.875), F(-0x1.db11ed766abf432ep-5)], + [F(10), F(0x1p+0)], [F(100), F(0x1p+1)], [F(10000), F(0x1p+2)], ]; testLog10(vals); }} @@ -3758,7 +3763,7 @@ private T log1pImpl(T)(T x) @safe pure nothrow @nogc } static foreach (F; AliasSeq!(float, double, real)) {{ - F[2][24] vals = [ + scope F[2][] vals = [ [F(1), F(0x1.62e42fefa39ef358p-1)], [F(2), F(0x1.193ea7aad030a976p+0)], [F(4), F(0x1.9c041f7ed8d336bp+0)], [F(8), F(0x1.193ea7aad030a976p+1)], [F(16), F(0x1.6aa6bc1fa7f79cfp+1)], [F(32), F(0x1.bf8d8f4d5b8d1038p+1)], @@ -3770,6 +3775,9 @@ private T log1pImpl(T)(T x) @safe pure nothrow @nogc [F(17), F(0x1.71f7b3a6b918664cp+1)], [F(31), F(0x1.bb9d3beb8c86b02ep+1)], [F(33), F(0x1.c35fc81b90df59c6p+1)], [F(63), F(0x1.0a2b23f3bab73682p+2)], [F(65), F(0x1.0c234da4a23a6686p+2)], [F(-0), F(-0x0p+0)], [F(0), F(0x0p+0)], + [F(0.1), F(0x1.8663f793c46c69cp-4)], [F(0.25), F(0x1.c8ff7c79a9a21ac4p-3)], + [F(0.75), F(0x1.1e85f5e7040d03ep-1)], [F(0.875), F(0x1.41d8fe84672ae646p-1)], + [F(10), F(0x1.32ee3b77f374bb7cp+1)], [F(100), F(0x1.275e2271bba30be4p+2)], [F(10000), F(0x1.26bbed6fbd84182ep+3)], ]; testLog1p(vals); @@ -3981,7 +3989,7 @@ Ldone: } static foreach (F; AliasSeq!(float, double, real)) {{ - F[2][24] vals = [ + scope F[2][] vals = [ [F(1), F(0x0p+0)], [F(2), F(0x1p+0)], [F(4), F(0x1p+1)], [F(8), F(0x1.8p+1)], [F(16), F(0x1p+2)], [F(32), F(0x1.4p+2)], @@ -3993,6 +4001,9 @@ Ldone: [F(17), F(0x1.0598fdbeb244c5ap+2)], [F(31), F(0x1.3d118d66c4d4e554p+2)], [F(33), F(0x1.42d75a6eb1dfb0e6p+2)], [F(63), F(0x1.7e8bc1179e0caa9cp+2)], [F(65), F(0x1.816e79685c2d2298p+2)], [F(-0), -F.infinity], [F(0), -F.infinity], + [F(0.1), F(-0x1.a934f0979a3715fcp+1)], [F(0.25), F(-0x1p+1)], + [F(0.75), F(-0x1.a8ff971810a5e182p-2)], [F(0.875), F(-0x1.8a8980abfbd32668p-3)], + [F(10), F(0x1.a934f0979a3715fcp+1)], [F(100), F(0x1.a934f0979a3715fcp+2)], [F(10000), F(0x1.a934f0979a3715fcp+3)], ]; testLog2(vals); @@ -4178,7 +4189,7 @@ private T logbImpl(T)(T x) @trusted pure nothrow @nogc } static foreach (F; AliasSeq!(float, double, real)) {{ - F[2][24] vals = [ + scope F[2][] vals = [ [F(1), F(0x0p+0)], [F(2), F(0x1p+0)], [F(4), F(0x1p+1)], [F(8), F(0x1.8p+1)], [F(16), F(0x1p+2)], [F(32), F(0x1.4p+2)], @@ -4190,6 +4201,9 @@ private T logbImpl(T)(T x) @trusted pure nothrow @nogc [F(17), F(0x1p+2)], [F(31), F(0x1p+2)], [F(33), F(0x1.4p+2)], [F(63), F(0x1.4p+2)], [F(65), F(0x1.8p+2)], [F(-0), -F.infinity], [F(0), -F.infinity], + [F(0.1), F(-0x1p+2)], [F(0.25), F(-0x1p+1)], + [F(0.75), F(-0x1p+0)], [F(0.875), F(-0x1p+0)], + [F(10), F(0x1.8p+1)], [F(100), F(0x1.8p+2)], [F(10000), F(0x1.ap+3)], ]; testLogb(vals); diff --git a/libphobos/src/std/traits.d b/libphobos/src/std/traits.d index bbbca69b22b..f4d011bbad9 100644 --- a/libphobos/src/std/traits.d +++ b/libphobos/src/std/traits.d @@ -8812,6 +8812,30 @@ template getSymbolsByUDA(alias symbol, alias attribute) static assert(is(getSymbolsByUDA!(X, X) == AliasSeq!())); } +// https://issues.dlang.org/show_bug.cgi?id=23776 +@safe pure nothrow @nogc unittest +{ + struct T + { + struct Tag {} + @Tag struct MyStructA {} + @Tag struct MyStructB {} + @Tag struct MyStructC {} + } + alias tcomponents = getSymbolsByUDA!(T, T.Tag); + static assert(tcomponents.length > 0); + + struct X + { + struct Tag {} + @Tag enum MyEnumA; + @Tag enum MyEnumB; + @Tag enum MyEnumC; + } + alias xcomponents = getSymbolsByUDA!(X, X.Tag); + static assert(xcomponents.length > 0); +} + // getSymbolsByUDA produces wrong result if one of the symbols having the UDA is a function // https://issues.dlang.org/show_bug.cgi?id=18624 @safe unittest @@ -8866,7 +8890,8 @@ private template getSymbolsByUDAImpl(alias symbol, alias attribute, names...) alias member = __traits(getMember, symbol, names[0]); // Filtering not compiled members such as alias of basic types. - static if (isAliasSeq!member || isType!member) + static if (isAliasSeq!member || + (isType!member && !isAggregateType!member && !is(member == enum))) { alias getSymbolsByUDAImpl = tail; }