public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r13-4602] d: Merge upstream dmd, druntime c8ae4adb2e, phobos 792c8b7c1.
@ 2022-12-11 16:18 Iain Buclaw
  0 siblings, 0 replies; only message in thread
From: Iain Buclaw @ 2022-12-11 16:18 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:6d799f0aed18be25a5c908499b6411ab6d06b78c

commit r13-4602-g6d799f0aed18be25a5c908499b6411ab6d06b78c
Author: Iain Buclaw <ibuclaw@gdcproject.org>
Date:   Fri Dec 9 18:59:38 2022 +0100

    d: Merge upstream dmd, druntime c8ae4adb2e, phobos 792c8b7c1.
    
    D front-end changes:
    
            - Import dmd v2.101.0.
            - Deprecate the ability to call `__traits(getAttributes)' on
              overload sets.
            - Deprecate non-empty `for' statement increment clause with no
              effect.
            - Array literals assigned to `scope' array variables can now be
              allocated on the stack.
    
    D runtime changes:
    
            - Import druntime v2.101.0.
    
    Phobos changes:
    
            - Import phobos v2.101.0.
    
    gcc/d/ChangeLog:
    
            * dmd/MERGE: Merge upstream dmd c8ae4adb2e.
            * typeinfo.cc (check_typeinfo_type): Update for new front-end
            interface.
            (TypeInfoVisitor::visit (TypeInfoStructDeclaration *)): Remove warning
            that toHash() must be declared 'nothrow @safe`.
    
    libphobos/ChangeLog:
    
            * libdruntime/MERGE: Merge upstream druntime c8ae4adb2e.
            * src/MERGE: Merge upstream phobos 792c8b7c1.

Diff:
---
 gcc/d/dmd/MERGE                                    |   2 +-
 gcc/d/dmd/aggregate.d                              |   8 +-
 gcc/d/dmd/attrib.d                                 |  14 +-
 gcc/d/dmd/blockexit.d                              |   4 +-
 gcc/d/dmd/canthrow.d                               |   2 +-
 gcc/d/dmd/clone.d                                  |  20 +-
 gcc/d/dmd/cond.d                                   |   6 +-
 gcc/d/dmd/constfold.d                              |  56 ++--
 gcc/d/dmd/cparse.d                                 |   8 +-
 gcc/d/dmd/cppmangle.d                              |  22 +-
 gcc/d/dmd/ctfeexpr.d                               |  86 +++---
 gcc/d/dmd/dcast.d                                  |  40 +--
 gcc/d/dmd/dclass.d                                 |  29 ++-
 gcc/d/dmd/declaration.d                            |  14 +-
 gcc/d/dmd/delegatize.d                             |   2 +-
 gcc/d/dmd/denum.d                                  |   4 +-
 gcc/d/dmd/dimport.d                                |  12 +-
 gcc/d/dmd/dinterpret.d                             | 136 +++++-----
 gcc/d/dmd/dmangle.d                                |  12 +-
 gcc/d/dmd/dmodule.d                                |  30 +--
 gcc/d/dmd/doc.d                                    |  54 ++--
 gcc/d/dmd/dscope.d                                 |  29 ++-
 gcc/d/dmd/dstruct.d                                |  14 +-
 gcc/d/dmd/dsymbol.d                                |  48 ++--
 gcc/d/dmd/dsymbolsem.d                             | 169 ++++++------
 gcc/d/dmd/dtemplate.d                              | 288 +++++++++++----------
 gcc/d/dmd/dtoh.d                                   |   4 +-
 gcc/d/dmd/escape.d                                 |  73 +++---
 gcc/d/dmd/expression.d                             |  78 +++---
 gcc/d/dmd/expressionsem.d                          | 192 +++++++-------
 gcc/d/dmd/file_manager.d                           | 138 ++++++++--
 gcc/d/dmd/func.d                                   | 118 +++++----
 gcc/d/dmd/hdrgen.d                                 |  48 ++--
 gcc/d/dmd/iasmgcc.d                                |   6 +-
 gcc/d/dmd/init.d                                   |  16 +-
 gcc/d/dmd/initsem.d                                |  28 +-
 gcc/d/dmd/json.d                                   |  30 +--
 gcc/d/dmd/lambdacomp.d                             |   2 +-
 gcc/d/dmd/lexer.d                                  |  56 ++--
 gcc/d/dmd/mtype.d                                  |  36 +--
 gcc/d/dmd/nogc.d                                   |  10 +-
 gcc/d/dmd/ob.d                                     |   2 +-
 gcc/d/dmd/objc.d                                   |   4 +-
 gcc/d/dmd/opover.d                                 |  34 +--
 gcc/d/dmd/optimize.d                               |   4 +-
 gcc/d/dmd/parse.d                                  |  78 ++++--
 gcc/d/dmd/root/array.d                             |   4 +-
 gcc/d/dmd/root/filename.d                          |   2 +-
 gcc/d/dmd/root/utf.d                               |  20 ++
 gcc/d/dmd/sapply.d                                 |   6 +-
 gcc/d/dmd/scope.h                                  |  78 ++----
 gcc/d/dmd/semantic2.d                              |  14 +-
 gcc/d/dmd/semantic3.d                              |  24 +-
 gcc/d/dmd/statement.d                              |  12 +-
 gcc/d/dmd/statement_rewrite_walker.d               |  12 +-
 gcc/d/dmd/statementsem.d                           | 141 +++++-----
 gcc/d/dmd/traits.d                                 |  50 +++-
 gcc/d/dmd/transitivevisitor.d                      |   8 +-
 gcc/d/dmd/typesem.d                                |  70 ++---
 gcc/d/typeinfo.cc                                  |  13 +-
 gcc/testsuite/gdc.test/compilable/nogc.d           |   3 +-
 gcc/testsuite/gdc.test/compilable/test15712.d      |  12 +
 gcc/testsuite/gdc.test/compilable/test23431.d      |  14 +
 .../gdc.test/compilable/test23431_minimal.d        |  28 ++
 gcc/testsuite/gdc.test/compilable/test23433.d      |  16 ++
 gcc/testsuite/gdc.test/compilable/test23439.d      |   8 +
 gcc/testsuite/gdc.test/compilable/test23534.d      |   6 +
 gcc/testsuite/gdc.test/compilable/test4375.d       |   2 +-
 gcc/testsuite/gdc.test/compilable/vgc2.d           |   3 +-
 .../gdc.test/fail_compilation/diag14818.d          |  16 +-
 gcc/testsuite/gdc.test/fail_compilation/diag8101.d |   5 +-
 .../gdc.test/fail_compilation/diag_funclit.d       |  14 +-
 gcc/testsuite/gdc.test/fail_compilation/diagin.d   |   2 +-
 gcc/testsuite/gdc.test/fail_compilation/fail12.d   |   4 +-
 .../gdc.test/fail_compilation/fail15414.d          |  21 ++
 .../gdc.test/fail_compilation/fail15616b.d         |   1 -
 gcc/testsuite/gdc.test/fail_compilation/fail1900.d |   8 +-
 .../gdc.test/fail_compilation/fail22366.d          |  32 ++-
 .../gdc.test/fail_compilation/fail23439.d          |  13 +
 gcc/testsuite/gdc.test/fail_compilation/fail320.d  |   9 +-
 gcc/testsuite/gdc.test/fail_compilation/fail54.d   |  10 +-
 gcc/testsuite/gdc.test/fail_compilation/fail99.d   |   2 +-
 .../gdc.test/fail_compilation/fail_arrayop2.d      |   4 +-
 .../gdc.test/fail_compilation/fail_pretty_errors.d |  18 +-
 gcc/testsuite/gdc.test/fail_compilation/ice10922.d |   2 +-
 gcc/testsuite/gdc.test/fail_compilation/ice13459.d |   2 +-
 gcc/testsuite/gdc.test/fail_compilation/ice9540.d  |   2 +-
 .../gdc.test/fail_compilation/imports/fail320a.d   |   1 +
 .../gdc.test/fail_compilation/imports/fail320b.d   |   3 +-
 .../gdc.test/fail_compilation/lexer23465.d         |  21 ++
 gcc/testsuite/gdc.test/fail_compilation/misc1.d    |  22 ++
 gcc/testsuite/gdc.test/fail_compilation/nogc2.d    |   3 +-
 gcc/testsuite/gdc.test/fail_compilation/retscope.d |   4 +-
 .../gdc.test/fail_compilation/retscope2.d          |   4 +-
 .../gdc.test/fail_compilation/templateoverload.d   |  22 ++
 .../gdc.test/fail_compilation/test19646.d          |   8 +-
 .../gdc.test/fail_compilation/test21008.d          |   6 +-
 .../gdc.test/fail_compilation/test21062.d          |  24 ++
 .../gdc.test/fail_compilation/test23491.d          |  19 ++
 .../gdc.test/fail_compilation/test23536.d          |  19 ++
 gcc/testsuite/gdc.test/fail_compilation/throwexp.d |  12 +
 .../gdc.test/fail_compilation/warn14905.d          |  23 --
 gcc/testsuite/gdc.test/runnable/lexer.d            |   9 +-
 gcc/testsuite/gdc.test/runnable/test21301.d        | 116 +++++++++
 gcc/testsuite/gdc.test/runnable/test21506.d        |  40 +++
 libphobos/libdruntime/MERGE                        |   2 +-
 libphobos/libdruntime/core/demangle.d              | 101 +++++++-
 libphobos/libdruntime/core/exception.d             |  24 +-
 libphobos/libdruntime/core/internal/gc/os.d        |   3 -
 libphobos/libdruntime/core/runtime.d               |   2 +-
 libphobos/libdruntime/core/sync/condition.d        |  35 +--
 libphobos/libdruntime/core/sync/mutex.d            |   2 +-
 libphobos/libdruntime/core/sys/posix/sys/wait.d    |   1 +
 libphobos/libdruntime/core/sys/windows/winsock2.d  |   4 +-
 libphobos/src/MERGE                                |   2 +-
 libphobos/src/std/algorithm/mutation.d             |   2 +-
 libphobos/src/std/algorithm/sorting.d              |   2 +-
 libphobos/src/std/array.d                          |   9 +-
 libphobos/src/std/base64.d                         |   6 +-
 libphobos/src/std/bitmanip.d                       |   4 +-
 libphobos/src/std/checkedint.d                     |  18 +-
 libphobos/src/std/concurrency.d                    |   4 +-
 libphobos/src/std/container/array.d                |  28 +-
 libphobos/src/std/container/binaryheap.d           |   4 +-
 libphobos/src/std/conv.d                           |  26 +-
 libphobos/src/std/datetime/systime.d               |   4 +-
 libphobos/src/std/digest/hmac.d                    |   4 +-
 libphobos/src/std/exception.d                      |   8 +-
 .../allocator/building_blocks/package.d            |  12 +-
 libphobos/src/std/experimental/allocator/package.d |  17 +-
 libphobos/src/std/file.d                           |  13 +-
 libphobos/src/std/format/internal/write.d          |  20 +-
 libphobos/src/std/format/package.d                 |  31 ++-
 libphobos/src/std/format/write.d                   |  20 ++
 libphobos/src/std/getopt.d                         |   2 +-
 libphobos/src/std/math/hardware.d                  | 124 +++++----
 libphobos/src/std/process.d                        |  13 +-
 libphobos/src/std/range/package.d                  |  26 +-
 libphobos/src/std/socket.d                         |  29 ++-
 libphobos/src/std/stdio.d                          | 210 ++++++++-------
 libphobos/src/std/sumtype.d                        |  10 +-
 libphobos/src/std/traits.d                         |  28 +-
 libphobos/src/std/typecons.d                       |  10 +-
 libphobos/src/std/uni/package.d                    |   4 +-
 libphobos/src/std/utf.d                            |   4 +-
 libphobos/src/std/windows/registry.d               |   2 +-
 146 files changed, 2457 insertions(+), 1546 deletions(-)

diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE
index 2398875bce7..5ee6f624836 100644
--- a/gcc/d/dmd/MERGE
+++ b/gcc/d/dmd/MERGE
@@ -1,4 +1,4 @@
-e4f89195913be1dc638707b1abb24c4f3ae7e0bf
+c8ae4adb2eda515b09b326948e3a4aa9f489af45
 
 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/aggregate.d b/gcc/d/dmd/aggregate.d
index e9e8bbe4e27..50fdc3b7da7 100644
--- a/gcc/d/dmd/aggregate.d
+++ b/gcc/d/dmd/aggregate.d
@@ -193,7 +193,7 @@ extern (C++) abstract class AggregateDeclaration : ScopeDsymbol
      */
     final size_t nonHiddenFields()
     {
-        return fields.dim - isNested() - (vthis2 !is null);
+        return fields.length - isNested() - (vthis2 !is null);
     }
 
     /***************************************
@@ -274,7 +274,7 @@ extern (C++) abstract class AggregateDeclaration : ScopeDsymbol
     {
         //printf("AggregateDeclaration::checkOverlappedFields() %s\n", toChars());
         assert(sizeok == Sizeok.done);
-        size_t nfields = fields.dim;
+        size_t nfields = fields.length;
         if (isNested())
         {
             auto cd = isClassDeclaration();
@@ -362,7 +362,7 @@ extern (C++) abstract class AggregateDeclaration : ScopeDsymbol
         const nfields = nonHiddenFields();
         bool errors = false;
 
-        size_t dim = elements.dim;
+        size_t dim = elements.length;
         elements.setDim(nfields);
         foreach (size_t i; dim .. nfields)
             elements[i] = null;
@@ -774,7 +774,7 @@ extern (C++) abstract class AggregateDeclaration : ScopeDsymbol
                 }
             }
 
-            for (size_t i = 0; i < members.dim; i++)
+            for (size_t i = 0; i < members.length; i++)
             {
                 auto sm = (*members)[i];
                 sm.apply(&SearchCtor.fp, null);
diff --git a/gcc/d/dmd/attrib.d b/gcc/d/dmd/attrib.d
index 3f27cb990b0..55d69b555f8 100644
--- a/gcc/d/dmd/attrib.d
+++ b/gcc/d/dmd/attrib.d
@@ -781,7 +781,7 @@ extern (C++) final class AnonDeclaration : AttribDeclaration
              * so in order to place that member we need to compute the member's
              * size and alignment.
              */
-            size_t fieldstart = ad.fields.dim;
+            size_t fieldstart = ad.fields.length;
 
             /* Hackishly hijack ad's structsize and alignsize fields
              * for use in our fake anon aggregate member.
@@ -804,7 +804,7 @@ extern (C++) final class AnonDeclaration : AttribDeclaration
              * added in ad.fields, just update *poffset for the subsequent
              * field offset calculation.
              */
-            if (fieldstart == ad.fields.dim)
+            if (fieldstart == ad.fields.length)
             {
                 ad.structsize = savestructsize;
                 ad.alignsize = savealignsize;
@@ -838,7 +838,7 @@ extern (C++) final class AnonDeclaration : AttribDeclaration
 
             // Add to the anon fields the base offset of this anonymous aggregate
             //printf("anon fields, anonoffset = %d\n", anonoffset);
-            foreach (const i; fieldstart .. ad.fields.dim)
+            foreach (const i; fieldstart .. ad.fields.length)
             {
                 VarDeclaration v = ad.fields[i];
                 //printf("\t[%d] %s %d\n", i, v.toChars(), v.offset);
@@ -1349,7 +1349,7 @@ extern (C++) final class UserAttributeDeclaration : AttribDeclaration
     override Scope* newScope(Scope* sc)
     {
         Scope* sc2 = sc;
-        if (atts && atts.dim)
+        if (atts && atts.length)
         {
             // create new one for changes
             sc2 = sc.copy();
@@ -1369,9 +1369,9 @@ extern (C++) final class UserAttributeDeclaration : AttribDeclaration
     extern (D) static Expressions* concat(Expressions* udas1, Expressions* udas2)
     {
         Expressions* udas;
-        if (!udas1 || udas1.dim == 0)
+        if (!udas1 || udas1.length == 0)
             udas = udas2;
-        else if (!udas2 || udas2.dim == 0)
+        else if (!udas2 || udas2.length == 0)
             udas = udas1;
         else
         {
@@ -1395,7 +1395,7 @@ extern (C++) final class UserAttributeDeclaration : AttribDeclaration
         auto exps = new Expressions();
         if (userAttribDecl && userAttribDecl !is this)
             exps.push(new TupleExp(Loc.initial, userAttribDecl.getAttributes()));
-        if (atts && atts.dim)
+        if (atts && atts.length)
             exps.push(new TupleExp(Loc.initial, atts));
         return exps;
     }
diff --git a/gcc/d/dmd/blockexit.d b/gcc/d/dmd/blockexit.d
index 22c9dde5f7e..64568763a87 100644
--- a/gcc/d/dmd/blockexit.d
+++ b/gcc/d/dmd/blockexit.d
@@ -122,7 +122,7 @@ int blockExit(Statement s, FuncDeclaration func, bool mustNotThrow)
 
         override void visit(CompoundStatement cs)
         {
-            //printf("CompoundStatement.blockExit(%p) %d result = x%X\n", cs, cs.statements.dim, result);
+            //printf("CompoundStatement.blockExit(%p) %d result = x%X\n", cs, cs.statements.length, result);
             result = BE.fallthru;
             Statement slast = null;
             foreach (s; *cs.statements)
@@ -547,7 +547,7 @@ BE checkThrow(ref const Loc loc, Expression exp, const bool mustNotThrow)
     ClassDeclaration cd = t.isClassHandle();
     assert(cd);
 
-    if (cd == ClassDeclaration.errorException || ClassDeclaration.errorException.isBaseOf(cd, null))
+    if (cd.isErrorException())
     {
         return BE.errthrow;
     }
diff --git a/gcc/d/dmd/canthrow.d b/gcc/d/dmd/canthrow.d
index 09e38331137..cb9289fd773 100644
--- a/gcc/d/dmd/canthrow.d
+++ b/gcc/d/dmd/canthrow.d
@@ -102,7 +102,7 @@ extern (C++) /* CT */ BE canThrow(Expression e, FuncDeclaration func, bool mustN
             if (global.errors && !ce.e1.type)
                 return; // error recovery
 
-            if (ce.f && ce.arguments.dim > 0)
+            if (ce.f && ce.arguments.length > 0)
             {
                 Type tb = (*ce.arguments)[0].type.toBasetype();
                 auto tbNext = tb.nextOf();
diff --git a/gcc/d/dmd/clone.d b/gcc/d/dmd/clone.d
index c999048dc49..c030d353c18 100644
--- a/gcc/d/dmd/clone.d
+++ b/gcc/d/dmd/clone.d
@@ -870,17 +870,17 @@ void buildDtors(AggregateDeclaration ad, Scope* sc)
         return;                    // unions don't have destructors
 
     StorageClass stc = STC.safe | STC.nothrow_ | STC.pure_ | STC.nogc;
-    Loc declLoc = ad.userDtors.dim ? ad.userDtors[0].loc : ad.loc;
+    Loc declLoc = ad.userDtors.length ? ad.userDtors[0].loc : ad.loc;
     Loc loc; // internal code should have no loc to prevent coverage
     FuncDeclaration xdtor_fwd = null;
 
     // Build the field destructor (`ad.fieldDtor`), if needed.
     // If the user dtor is an extern(C++) prototype, then we expect it performs a full-destruction and skip building.
-    const bool dtorIsCppPrototype = ad.userDtors.dim && ad.userDtors[0]._linkage == LINK.cpp && !ad.userDtors[0].fbody;
+    const bool dtorIsCppPrototype = ad.userDtors.length && ad.userDtors[0]._linkage == LINK.cpp && !ad.userDtors[0].fbody;
     if (!dtorIsCppPrototype)
     {
         Expression e = null;
-        for (size_t i = 0; i < ad.fields.dim; i++)
+        for (size_t i = 0; i < ad.fields.length; i++)
         {
             auto v = ad.fields[i];
             if (v.storage_class & STC.ref_)
@@ -985,7 +985,7 @@ void buildDtors(AggregateDeclaration ad, Scope* sc)
     }
 
     // Set/build `ad.aggrDtor`
-    switch (dtors.dim)
+    switch (dtors.length)
     {
     case 0:
         break;
@@ -1168,7 +1168,7 @@ private DtorDeclaration buildExternDDtor(AggregateDeclaration ad, Scope* sc)
  */
 FuncDeclaration buildInv(AggregateDeclaration ad, Scope* sc)
 {
-    switch (ad.invs.dim)
+    switch (ad.invs.length)
     {
     case 0:
         return null;
@@ -1225,11 +1225,11 @@ FuncDeclaration buildPostBlit(StructDeclaration sd, Scope* sc)
     if (sd.isUnionDeclaration())
         return null;
 
-    const hasUserDefinedPosblit = sd.postblits.dim && !sd.postblits[0].isDisabled ? true : false;
+    const hasUserDefinedPosblit = sd.postblits.length && !sd.postblits[0].isDisabled ? true : false;
 
     // by default, the storage class of the created postblit
     StorageClass stc = STC.safe | STC.nothrow_ | STC.pure_ | STC.nogc;
-    Loc declLoc = sd.postblits.dim ? sd.postblits[0].loc : sd.loc;
+    Loc declLoc = sd.postblits.length ? sd.postblits[0].loc : sd.loc;
     Loc loc; // internal code should have no loc to prevent coverage
 
     // if any of the postblits are disabled, then the generated postblit
@@ -1240,7 +1240,7 @@ FuncDeclaration buildPostBlit(StructDeclaration sd, Scope* sc)
     VarDeclaration[] fieldsToDestroy;
     auto postblitCalls = new Statements();
     // iterate through all the struct fields that are not disabled
-    for (size_t i = 0; i < sd.fields.dim && !(stc & STC.disable); i++)
+    for (size_t i = 0; i < sd.fields.length && !(stc & STC.disable); i++)
     {
         auto structField = sd.fields[i];
         if (structField.storage_class & STC.ref_)
@@ -1411,7 +1411,7 @@ FuncDeclaration buildPostBlit(StructDeclaration sd, Scope* sc)
     }
 
     // Build our own "postblit" which executes a, but only if needed.
-    if (postblitCalls.dim || (stc & STC.disable))
+    if (postblitCalls.length || (stc & STC.disable))
     {
         //printf("Building __fieldPostBlit()\n");
         checkShared();
@@ -1426,7 +1426,7 @@ FuncDeclaration buildPostBlit(StructDeclaration sd, Scope* sc)
 
     // create __xpostblit, which is the generated postblit
     FuncDeclaration xpostblit = null;
-    switch (sd.postblits.dim)
+    switch (sd.postblits.length)
     {
     case 0:
         break;
diff --git a/gcc/d/dmd/cond.d b/gcc/d/dmd/cond.d
index 65085f544f7..c1e1e4d8d24 100644
--- a/gcc/d/dmd/cond.d
+++ b/gcc/d/dmd/cond.d
@@ -222,7 +222,7 @@ extern (C++) final class StaticForeach : RootObject
         }
         else
         {
-            assert(rangefe && parameters.dim == 1);
+            assert(rangefe && parameters.length == 1);
             return new ForeachRangeStatement(loc, rangefe.op, (*parameters)[0], rangefe.lwr.syntaxCopy(), rangefe.upr.syntaxCopy(), s, loc);
         }
     }
@@ -306,7 +306,7 @@ extern (C++) final class StaticForeach : RootObject
 
     private void lowerNonArrayAggregate(Scope* sc)
     {
-        auto nvars = aggrfe ? aggrfe.parameters.dim : 1;
+        auto nvars = aggrfe ? aggrfe.parameters.length : 1;
         auto aloc = aggrfe ? aggrfe.aggr.loc : rangefe.lwr.loc;
         // We need three sets of foreach loop variables because the
         // lowering contains three foreach loops.
@@ -332,7 +332,7 @@ extern (C++) final class StaticForeach : RootObject
         {
             foreach (i; 0 .. 2)
             {
-                auto e = new Expressions(pparams[0].dim);
+                auto e = new Expressions(pparams[0].length);
                 foreach (j, ref elem; *e)
                 {
                     auto p = (*pparams[i])[j];
diff --git a/gcc/d/dmd/constfold.d b/gcc/d/dmd/constfold.d
index f4e44e812c8..ef684ba745f 100644
--- a/gcc/d/dmd/constfold.d
+++ b/gcc/d/dmd/constfold.d
@@ -644,7 +644,7 @@ UnionExp Equal(EXP op, const ref Loc loc, Type type, Expression e1, Expression e
         }
         else if (ArrayLiteralExp es2 = e2.isArrayLiteralExp())
         {
-            cmp = !es2.elements || (0 == es2.elements.dim);
+            cmp = !es2.elements || (0 == es2.elements.length);
         }
         else
         {
@@ -660,7 +660,7 @@ UnionExp Equal(EXP op, const ref Loc loc, Type type, Expression e1, Expression e
         }
         else if (ArrayLiteralExp es1 = e1.isArrayLiteralExp())
         {
-            cmp = !es1.elements || (0 == es1.elements.dim);
+            cmp = !es1.elements || (0 == es1.elements.length);
         }
         else
         {
@@ -689,15 +689,15 @@ UnionExp Equal(EXP op, const ref Loc loc, Type type, Expression e1, Expression e
     {
         ArrayLiteralExp es1 = e1.isArrayLiteralExp();
         ArrayLiteralExp es2 = e2.isArrayLiteralExp();
-        if ((!es1.elements || !es1.elements.dim) && (!es2.elements || !es2.elements.dim))
+        if ((!es1.elements || !es1.elements.length) && (!es2.elements || !es2.elements.length))
             cmp = 1; // both arrays are empty
         else if (!es1.elements || !es2.elements)
             cmp = 0;
-        else if (es1.elements.dim != es2.elements.dim)
+        else if (es1.elements.length != es2.elements.length)
             cmp = 0;
         else
         {
-            for (size_t i = 0; i < es1.elements.dim; i++)
+            for (size_t i = 0; i < es1.elements.length; i++)
             {
                 auto ee1 = es1[i];
                 auto ee2 = es2[i];
@@ -724,7 +724,7 @@ UnionExp Equal(EXP op, const ref Loc loc, Type type, Expression e1, Expression e
         StringExp es1 = e1.isStringExp();
         ArrayLiteralExp es2 = e2.isArrayLiteralExp();
         size_t dim1 = es1.len;
-        size_t dim2 = es2.elements ? es2.elements.dim : 0;
+        size_t dim2 = es2.elements ? es2.elements.length : 0;
         if (dim1 != dim2)
             cmp = 0;
         else
@@ -751,16 +751,16 @@ UnionExp Equal(EXP op, const ref Loc loc, Type type, Expression e1, Expression e
         StructLiteralExp es2 = e2.isStructLiteralExp();
         if (es1.sd != es2.sd)
             cmp = 0;
-        else if ((!es1.elements || !es1.elements.dim) && (!es2.elements || !es2.elements.dim))
+        else if ((!es1.elements || !es1.elements.length) && (!es2.elements || !es2.elements.length))
             cmp = 1; // both arrays are empty
         else if (!es1.elements || !es2.elements)
             cmp = 0;
-        else if (es1.elements.dim != es2.elements.dim)
+        else if (es1.elements.length != es2.elements.length)
             cmp = 0;
         else
         {
             cmp = 1;
-            for (size_t i = 0; i < es1.elements.dim; i++)
+            for (size_t i = 0; i < es1.elements.length; i++)
             {
                 Expression ee1 = (*es1.elements)[i];
                 Expression ee2 = (*es2.elements)[i];
@@ -1074,7 +1074,7 @@ UnionExp Cast(const ref Loc loc, Type type, Type to, Expression e1)
         StructDeclaration sd = tb.toDsymbol(null).isStructDeclaration();
         assert(sd);
         auto elements = new Expressions();
-        for (size_t i = 0; i < sd.fields.dim; i++)
+        for (size_t i = 0; i < sd.fields.length; i++)
         {
             VarDeclaration v = sd.fields[i];
             UnionExp zero;
@@ -1110,12 +1110,12 @@ UnionExp ArrayLength(Type type, Expression e1)
     }
     else if (ArrayLiteralExp ale = e1.isArrayLiteralExp())
     {
-        size_t dim = ale.elements ? ale.elements.dim : 0;
+        size_t dim = ale.elements ? ale.elements.length : 0;
         emplaceExp!(IntegerExp)(&ue, loc, dim, type);
     }
     else if (AssocArrayLiteralExp ale = e1.isAssocArrayLiteralExp)
     {
-        size_t dim = ale.keys.dim;
+        size_t dim = ale.keys.length;
         emplaceExp!(IntegerExp)(&ue, loc, dim, type);
     }
     else if (e1.type.toBasetype().ty == Tsarray)
@@ -1183,9 +1183,9 @@ UnionExp Index(Type type, Expression e1, Expression e2, bool indexIsInBounds)
         uinteger_t i = e2.toInteger();
         if (ArrayLiteralExp ale = e1.isArrayLiteralExp())
         {
-            if (i >= ale.elements.dim)
+            if (i >= ale.elements.length)
             {
-                e1.error("array index %llu is out of bounds `%s[0 .. %llu]`", i, e1.toChars(), cast(ulong) ale.elements.dim);
+                e1.error("array index %llu is out of bounds `%s[0 .. %llu]`", i, e1.toChars(), cast(ulong) ale.elements.length);
                 emplaceExp!(ErrorExp)(&ue);
             }
             else
@@ -1206,7 +1206,7 @@ UnionExp Index(Type type, Expression e1, Expression e2, bool indexIsInBounds)
     {
         /* Search the keys backwards, in case there are duplicate keys
          */
-        for (size_t i = ae.keys.dim; i;)
+        for (size_t i = ae.keys.length; i;)
         {
             i--;
             Expression ekey = (*ae.keys)[i];
@@ -1274,7 +1274,7 @@ UnionExp Slice(Type type, Expression e1, Expression lwr, Expression upr)
         ArrayLiteralExp es1 = e1.isArrayLiteralExp();
         const uinteger_t ilwr = lwr.toInteger();
         const uinteger_t iupr = upr.toInteger();
-        if (sliceBoundsCheck(0, es1.elements.dim, ilwr, iupr))
+        if (sliceBoundsCheck(0, es1.elements.length, ilwr, iupr))
             cantExp(ue);
         else
         {
@@ -1318,7 +1318,7 @@ void sliceAssignArrayLiteralFromString(ArrayLiteralExp existingAE, const StringE
 void sliceAssignStringFromArrayLiteral(StringExp existingSE, ArrayLiteralExp newae, size_t firstIndex)
 {
     assert(existingSE.ownedByCtfe != OwnedBy.code);
-    foreach (j; 0 .. newae.elements.dim)
+    foreach (j; 0 .. newae.elements.length)
     {
         existingSE.setCodeUnit(firstIndex + j, cast(dchar)newae[j].toInteger());
     }
@@ -1383,9 +1383,9 @@ private Expressions* copyElements(Expression e1, Expression e2 = null)
     {
         if (!ale.elements)
             return;
-        auto d = elems.dim;
+        auto d = elems.length;
         elems.append(ale.elements);
-        foreach (ref el; (*elems)[d .. elems.dim])
+        foreach (ref el; (*elems)[d .. elems.length])
         {
             if (!el)
                 el = ale.basis;
@@ -1524,15 +1524,15 @@ UnionExp Cat(const ref Loc loc, Type type, Expression e1, Expression e2)
         // [chars] ~ string --> [chars]
         StringExp es = e2.isStringExp();
         ArrayLiteralExp ea = e1.isArrayLiteralExp();
-        size_t len = es.len + ea.elements.dim;
+        size_t len = es.len + ea.elements.length;
         auto elems = new Expressions(len);
-        for (size_t i = 0; i < ea.elements.dim; ++i)
+        for (size_t i = 0; i < ea.elements.length; ++i)
         {
             (*elems)[i] = ea[i];
         }
         emplaceExp!(ArrayLiteralExp)(&ue, e1.loc, type, elems);
         ArrayLiteralExp dest = ue.exp().isArrayLiteralExp();
-        sliceAssignArrayLiteralFromString(dest, es, ea.elements.dim);
+        sliceAssignArrayLiteralFromString(dest, es, ea.elements.length);
         assert(ue.exp().type);
         return ue;
     }
@@ -1541,9 +1541,9 @@ UnionExp Cat(const ref Loc loc, Type type, Expression e1, Expression e2)
         // string ~ [chars] --> [chars]
         StringExp es = e1.isStringExp();
         ArrayLiteralExp ea = e2.isArrayLiteralExp();
-        size_t len = es.len + ea.elements.dim;
+        size_t len = es.len + ea.elements.length;
         auto elems = new Expressions(len);
-        for (size_t i = 0; i < ea.elements.dim; ++i)
+        for (size_t i = 0; i < ea.elements.length; ++i)
         {
             (*elems)[es.len + i] = ea[i];
         }
@@ -1609,7 +1609,7 @@ UnionExp Cat(const ref Loc loc, Type type, Expression e1, Expression e2)
         e = ue.exp();
         if (type.toBasetype().ty == Tsarray)
         {
-            e.type = t1.nextOf().sarrayOf(elems.dim);
+            e.type = t1.nextOf().sarrayOf(elems.length);
         }
         else
             e.type = type;
@@ -1633,7 +1633,7 @@ UnionExp Cat(const ref Loc loc, Type type, Expression e1, Expression e2)
         e = ue.exp();
         if (type.toBasetype().ty == Tsarray)
         {
-            e.type = t1.nextOf().sarrayOf(elems.dim);
+            e.type = t1.nextOf().sarrayOf(elems.length);
         }
         else
             e.type = type;
@@ -1651,7 +1651,7 @@ UnionExp Cat(const ref Loc loc, Type type, Expression e1, Expression e2)
         e = ue.exp();
         if (type.toBasetype().ty == Tsarray)
         {
-            e.type = e2.type.sarrayOf(elems.dim);
+            e.type = e2.type.sarrayOf(elems.length);
         }
         else
             e.type = type;
@@ -1667,7 +1667,7 @@ UnionExp Cat(const ref Loc loc, Type type, Expression e1, Expression e2)
         e = ue.exp();
         if (type.toBasetype().ty == Tsarray)
         {
-            e.type = e1.type.sarrayOf(elems.dim);
+            e.type = e1.type.sarrayOf(elems.length);
         }
         else
             e.type = type;
diff --git a/gcc/d/dmd/cparse.d b/gcc/d/dmd/cparse.d
index ad1ad6791c5..d4416abe097 100644
--- a/gcc/d/dmd/cparse.d
+++ b/gcc/d/dmd/cparse.d
@@ -4816,7 +4816,13 @@ final class CParser(AST) : Parser!AST
         else if (auto tt = t.isTypeTag())
             tt.mod |= MODFlags.const_;
         else
-            t = t.addSTC(STC.const_);
+        {
+            /* Ignore const if the result would be const pointer to mutable
+             */
+            auto tn = t.nextOf();
+            if (!tn || tn.isConst())
+                t = t.addSTC(STC.const_);
+        }
         return t;
     }
 
diff --git a/gcc/d/dmd/cppmangle.d b/gcc/d/dmd/cppmangle.d
index 7c130e94862..fbe9f0181d4 100644
--- a/gcc/d/dmd/cppmangle.d
+++ b/gcc/d/dmd/cppmangle.d
@@ -534,10 +534,10 @@ private final class CppMangleVisitor : Visitor
     {
         /* <template-args> ::= I <template-arg>+ E
          */
-        if (!ti || ti.tiargs.dim <= firstArg)   // could happen if std::basic_string is not a template
+        if (!ti || ti.tiargs.length <= firstArg)   // could happen if std::basic_string is not a template
             return false;
         buf.writeByte('I');
-        foreach (i; firstArg .. ti.tiargs.dim)
+        foreach (i; firstArg .. ti.tiargs.length)
         {
             TemplateDeclaration td = ti.tempdecl.isTemplateDeclaration();
             assert(td);
@@ -556,7 +556,7 @@ private final class CppMangleVisitor : Visitor
                 buf.writeByte('J');     // argument pack
 
                 // mangle the rest of the arguments as types
-                foreach (j; i .. (*ti.tiargs).dim)
+                foreach (j; i .. (*ti.tiargs).length)
                 {
                     Type t = isType((*ti.tiargs)[j]);
                     assert(t);
@@ -760,7 +760,7 @@ private final class CppMangleVisitor : Visitor
             return false;
         Dsymbol q = getQualifier(ti);
         const bool inStd = isStd(q) || isStd(this.getTiNamespace(ti));
-        return inStd && ti.tiargs.dim == 1 && isChar((*ti.tiargs)[0]);
+        return inStd && ti.tiargs.length == 1 && isChar((*ti.tiargs)[0]);
     }
 
     /***
@@ -771,7 +771,7 @@ private final class CppMangleVisitor : Visitor
      */
     bool char_std_char_traits_char(TemplateInstance ti, string st)
     {
-        if (ti.tiargs.dim == 2 &&
+        if (ti.tiargs.length == 2 &&
             isChar((*ti.tiargs)[0]) &&
             isChar_traits_char((*ti.tiargs)[1]))
         {
@@ -851,7 +851,7 @@ private final class CppMangleVisitor : Visitor
         if (ti.name == Id.basic_string)
         {
             // ::std::basic_string<char, ::std::char_traits<char>, ::std::allocator<char>>
-            if (ti.tiargs.dim == 3 &&
+            if (ti.tiargs.length == 3 &&
                 isChar((*ti.tiargs)[0]) &&
                 isChar_traits_char((*ti.tiargs)[1]) &&
                 isAllocator_char((*ti.tiargs)[2]))
@@ -933,7 +933,7 @@ private final class CppMangleVisitor : Visitor
         else if (s.ident == Id.basic_string)
         {
             // ::std::basic_string<char, ::std::char_traits<char>, ::std::allocator<char>>
-            if (ti.tiargs.dim == 3 &&
+            if (ti.tiargs.length == 3 &&
                 isChar((*ti.tiargs)[0]) &&
                 isChar_traits_char((*ti.tiargs)[1]) &&
                 isAllocator_char((*ti.tiargs)[2]))
@@ -1224,7 +1224,7 @@ private final class CppMangleVisitor : Visitor
         case CppOperator.OpAssign:
             TemplateDeclaration td = ti.tempdecl.isTemplateDeclaration();
             assert(td);
-            assert(ti.tiargs.dim >= 1);
+            assert(ti.tiargs.length >= 1);
             TemplateParameter tp = (*td.parameters)[0];
             TemplateValueParameter tv = tp.isTemplateValueParameter();
             if (!tv || !tv.valType.isString())
@@ -2005,14 +2005,14 @@ extern(C++):
                 this.context.res = (*analyzed_ti.tiargs)[idx];
                 o.visitObject(this);
             }
-            if (analyzed_ti.tiargs.dim > t.tiargs.dim)
+            if (analyzed_ti.tiargs.length > t.tiargs.length)
             {
                 // If the resolved AST has more args than the parse one,
                 // we have default arguments
                 auto oparams = (cast(TemplateDeclaration)analyzed_ti.tempdecl).origParameters;
-                foreach (idx, arg; (*oparams)[t.tiargs.dim .. $])
+                foreach (idx, arg; (*oparams)[t.tiargs.length .. $])
                 {
-                    this.context.res = (*analyzed_ti.tiargs)[idx + t.tiargs.dim];
+                    this.context.res = (*analyzed_ti.tiargs)[idx + t.tiargs.length];
 
                     if (auto ttp = arg.isTemplateTypeParameter())
                         ttp.defaultType.accept(this);
diff --git a/gcc/d/dmd/ctfeexpr.d b/gcc/d/dmd/ctfeexpr.d
index 6243e74410c..1dc1f7d1784 100644
--- a/gcc/d/dmd/ctfeexpr.d
+++ b/gcc/d/dmd/ctfeexpr.d
@@ -62,17 +62,17 @@ extern (C++) final class ClassReferenceExp : Expression
     {
         ClassDeclaration cd = originalClass();
         uint fieldsSoFar = 0;
-        for (size_t j = 0; j < value.elements.dim; j++)
+        for (size_t j = 0; j < value.elements.length; j++)
         {
-            while (j - fieldsSoFar >= cd.fields.dim)
+            while (j - fieldsSoFar >= cd.fields.length)
             {
-                fieldsSoFar += cd.fields.dim;
+                fieldsSoFar += cd.fields.length;
                 cd = cd.baseClass;
             }
             VarDeclaration v2 = cd.fields[j - fieldsSoFar];
             if (fieldoffset == v2.offset && fieldtype.size() == v2.type.size())
             {
-                return cast(int)(value.elements.dim - fieldsSoFar - cd.fields.dim + (j - fieldsSoFar));
+                return cast(int)(value.elements.length - fieldsSoFar - cd.fields.length + (j - fieldsSoFar));
             }
         }
         return -1;
@@ -84,17 +84,17 @@ extern (C++) final class ClassReferenceExp : Expression
     {
         ClassDeclaration cd = originalClass();
         size_t fieldsSoFar = 0;
-        for (size_t j = 0; j < value.elements.dim; j++)
+        for (size_t j = 0; j < value.elements.length; j++)
         {
-            while (j - fieldsSoFar >= cd.fields.dim)
+            while (j - fieldsSoFar >= cd.fields.length)
             {
-                fieldsSoFar += cd.fields.dim;
+                fieldsSoFar += cd.fields.length;
                 cd = cd.baseClass;
             }
             VarDeclaration v2 = cd.fields[j - fieldsSoFar];
             if (v == v2)
             {
-                return cast(int)(value.elements.dim - fieldsSoFar - cd.fields.dim + (j - fieldsSoFar));
+                return cast(int)(value.elements.length - fieldsSoFar - cd.fields.length + (j - fieldsSoFar));
             }
         }
         return -1;
@@ -267,7 +267,7 @@ private Expressions* copyLiteralArray(Expressions* oldelems, Expression basis =
     if (!oldelems)
         return oldelems;
     incArrayAllocs();
-    auto newelems = new Expressions(oldelems.dim);
+    auto newelems = new Expressions(oldelems.length);
     foreach (i, el; *oldelems)
     {
         (*newelems)[i] = copyLiteral(el ? el : basis).copy();
@@ -318,7 +318,7 @@ UnionExp copyLiteral(Expression e)
          * an int[4] array can be initialized with a single int.
          */
         auto oldelems = sle.elements;
-        auto newelems = new Expressions(oldelems.dim);
+        auto newelems = new Expressions(oldelems.length);
         foreach (i, ref el; *newelems)
         {
             // We need the struct definition to detect block assignment
@@ -566,12 +566,12 @@ uinteger_t resolveArrayLength(Expression e)
         case EXP.arrayLiteral:
         {
             const ale = e.isArrayLiteralExp();
-            return ale.elements ? ale.elements.dim : 0;
+            return ale.elements ? ale.elements.length : 0;
         }
 
         case EXP.assocArrayLiteral:
         {
-            return e.isAssocArrayLiteralExp().keys.dim;
+            return e.isAssocArrayLiteralExp().keys.length;
         }
 
         default:
@@ -1312,15 +1312,15 @@ private int ctfeRawCmp(const ref Loc loc, Expression e1, Expression e2, bool ide
         // For structs, we only need to return 0 or 1 (< and > aren't legal).
         if (es1.sd != es2.sd)
             return 1;
-        else if ((!es1.elements || !es1.elements.dim) && (!es2.elements || !es2.elements.dim))
+        else if ((!es1.elements || !es1.elements.length) && (!es2.elements || !es2.elements.length))
             return 0; // both arrays are empty
         else if (!es1.elements || !es2.elements)
             return 1;
-        else if (es1.elements.dim != es2.elements.dim)
+        else if (es1.elements.length != es2.elements.length)
             return 1;
         else
         {
-            foreach (size_t i; 0 .. es1.elements.dim)
+            foreach (size_t i; 0 .. es1.elements.length)
             {
                 Expression ee1 = (*es1.elements)[i];
                 Expression ee2 = (*es2.elements)[i];
@@ -1344,8 +1344,8 @@ private int ctfeRawCmp(const ref Loc loc, Expression e1, Expression e2, bool ide
     {
         AssocArrayLiteralExp es1 = e1.isAssocArrayLiteralExp();
         AssocArrayLiteralExp es2 = e2.isAssocArrayLiteralExp();
-        size_t dim = es1.keys.dim;
-        if (es2.keys.dim != dim)
+        size_t dim = es1.keys.length;
+        if (es2.keys.length != dim)
             return 1;
         bool* used = cast(bool*)mem.xmalloc(bool.sizeof * dim);
         memset(used, 0, bool.sizeof * dim);
@@ -1376,11 +1376,11 @@ private int ctfeRawCmp(const ref Loc loc, Expression e1, Expression e2, bool ide
     }
     else if (e1.op == EXP.assocArrayLiteral && e2.op == EXP.null_)
     {
-        return e1.isAssocArrayLiteralExp.keys.dim != 0;
+        return e1.isAssocArrayLiteralExp.keys.length != 0;
     }
     else if (e1.op == EXP.null_ && e2.op == EXP.assocArrayLiteral)
     {
-        return e2.isAssocArrayLiteralExp.keys.dim != 0;
+        return e2.isAssocArrayLiteralExp.keys.length != 0;
     }
 
     error(loc, "CTFE internal error: bad compare of `%s` and `%s`", e1.toChars(), e2.toChars());
@@ -1461,12 +1461,12 @@ UnionExp ctfeCat(const ref Loc loc, Type type, Expression e1, Expression e2)
         // [chars] ~ string => string (only valid for CTFE)
         StringExp es1 = e2.isStringExp();
         ArrayLiteralExp es2 = e1.isArrayLiteralExp();
-        const len = es1.len + es2.elements.dim;
+        const len = es1.len + es2.elements.length;
         const sz = es1.sz;
         void* s = mem.xmalloc((len + 1) * sz);
         const data1 = es1.peekData();
-        memcpy(cast(char*)s + sz * es2.elements.dim, data1.ptr, data1.length);
-        foreach (size_t i; 0 .. es2.elements.dim)
+        memcpy(cast(char*)s + sz * es2.elements.length, data1.ptr, data1.length);
+        foreach (size_t i; 0 .. es2.elements.length)
         {
             Expression es2e = (*es2.elements)[i];
             if (es2e.op != EXP.int64)
@@ -1491,12 +1491,12 @@ UnionExp ctfeCat(const ref Loc loc, Type type, Expression e1, Expression e2)
         // Concatenate the strings
         StringExp es1 = e1.isStringExp();
         ArrayLiteralExp es2 = e2.isArrayLiteralExp();
-        const len = es1.len + es2.elements.dim;
+        const len = es1.len + es2.elements.length;
         const sz = es1.sz;
         void* s = mem.xmalloc((len + 1) * sz);
         auto slice = es1.peekData();
         memcpy(s, slice.ptr, slice.length);
-        foreach (size_t i; 0 .. es2.elements.dim)
+        foreach (size_t i; 0 .. es2.elements.length)
         {
             Expression es2e = (*es2.elements)[i];
             if (es2e.op != EXP.int64)
@@ -1523,7 +1523,7 @@ UnionExp ctfeCat(const ref Loc loc, Type type, Expression e1, Expression e2)
         ArrayLiteralExp es2 = e2.isArrayLiteralExp();
         emplaceExp!(ArrayLiteralExp)(&ue, es1.loc, type, copyLiteralArray(es1.elements));
         es1 = ue.exp().isArrayLiteralExp();
-        es1.elements.insert(es1.elements.dim, copyLiteralArray(es2.elements));
+        es1.elements.insert(es1.elements.length, copyLiteralArray(es2.elements));
         return ue;
     }
     if (e1.op == EXP.arrayLiteral && e2.op == EXP.null_ && t1.nextOf().equals(t2.nextOf()))
@@ -1549,7 +1549,7 @@ Expression findKeyInAA(const ref Loc loc, AssocArrayLiteralExp ae, Expression e2
 {
     /* Search the keys backwards, in case there are duplicate keys
      */
-    for (size_t i = ae.keys.dim; i;)
+    for (size_t i = ae.keys.length; i;)
     {
         --i;
         Expression ekey = (*ae.keys)[i];
@@ -1583,9 +1583,9 @@ Expression ctfeIndex(UnionExp* pue, const ref Loc loc, Type type, Expression e1,
 
     if (auto ale = e1.isArrayLiteralExp())
     {
-        if (indx >= ale.elements.dim)
+        if (indx >= ale.elements.length)
         {
-            error(loc, "array index %llu is out of bounds `%s[0 .. %llu]`", indx, e1.toChars(), cast(ulong)ale.elements.dim);
+            error(loc, "array index %llu is out of bounds `%s[0 .. %llu]`", indx, e1.toChars(), cast(ulong)ale.elements.length);
             return CTFEExp.cantexp;
         }
         Expression e = (*ale.elements)[cast(size_t)indx];
@@ -1685,9 +1685,9 @@ void assignInPlace(Expression dest, Expression src)
         newelems = src.isStructLiteralExp().elements;
         auto sd = dest.isStructLiteralExp().sd;
         const nfields = sd.nonHiddenFields();
-        const nvthis = sd.fields.dim - nfields;
-        if (nvthis && oldelems.dim >= nfields && oldelems.dim < newelems.dim)
-            foreach (_; 0 .. newelems.dim - oldelems.dim)
+        const nvthis = sd.fields.length - nfields;
+        if (nvthis && oldelems.length >= nfields && oldelems.length < newelems.length)
+            foreach (_; 0 .. newelems.length - oldelems.length)
                 oldelems.push(null);
     }
     else if (dest.op == EXP.arrayLiteral && src.op == EXP.arrayLiteral)
@@ -1715,8 +1715,8 @@ void assignInPlace(Expression dest, Expression src)
         printf("invalid op %d %d\n", src.op, dest.op);
         assert(0);
     }
-    assert(oldelems.dim == newelems.dim);
-    foreach (size_t i; 0 .. oldelems.dim)
+    assert(oldelems.length == newelems.length);
+    foreach (size_t i; 0 .. oldelems.length)
     {
         Expression e = (*newelems)[i];
         Expression o = (*oldelems)[i];
@@ -1744,7 +1744,7 @@ Expression assignAssocArrayElement(const ref Loc loc, AssocArrayLiteralExp aae,
     Expressions* keysx = aae.keys;
     Expressions* valuesx = aae.values;
     int updated = 0;
-    for (size_t j = valuesx.dim; j;)
+    for (size_t j = valuesx.length; j;)
     {
         j--;
         Expression ekey = (*aae.keys)[j];
@@ -2029,13 +2029,13 @@ void showCtfeExpr(Expression e, int level = 0)
     if (elements)
     {
         size_t fieldsSoFar = 0;
-        for (size_t i = 0; i < elements.dim; i++)
+        for (size_t i = 0; i < elements.length; i++)
         {
             Expression z = null;
             VarDeclaration v = null;
             if (i > 15)
             {
-                printf("...(total %d elements)\n", cast(int)elements.dim);
+                printf("...(total %d elements)\n", cast(int)elements.length);
                 return;
             }
             if (sd)
@@ -2045,18 +2045,18 @@ void showCtfeExpr(Expression e, int level = 0)
             }
             else if (cd)
             {
-                while (i - fieldsSoFar >= cd.fields.dim)
+                while (i - fieldsSoFar >= cd.fields.length)
                 {
-                    fieldsSoFar += cd.fields.dim;
+                    fieldsSoFar += cd.fields.length;
                     cd = cd.baseClass;
                     for (int j = level; j > 0; --j)
                         printf(" ");
                     printf(" BASE CLASS: %s\n", cd.toChars());
                 }
                 v = cd.fields[i - fieldsSoFar];
-                assert((elements.dim + i) >= (fieldsSoFar + cd.fields.dim));
-                size_t indx = (elements.dim - fieldsSoFar) - cd.fields.dim + i;
-                assert(indx < elements.dim);
+                assert((elements.length + i) >= (fieldsSoFar + cd.fields.length));
+                size_t indx = (elements.length - fieldsSoFar) - cd.fields.length + i;
+                assert(indx < elements.length);
                 z = (*elements)[indx];
             }
             if (!z)
@@ -2108,8 +2108,8 @@ UnionExp voidInitLiteral(Type t, VarDeclaration var)
     else if (t.ty == Tstruct)
     {
         TypeStruct ts = cast(TypeStruct)t;
-        auto exps = new Expressions(ts.sym.fields.dim);
-        foreach (size_t i;  0 .. ts.sym.fields.dim)
+        auto exps = new Expressions(ts.sym.fields.length);
+        foreach (size_t i;  0 .. ts.sym.fields.length)
         {
             (*exps)[i] = voidInitLiteral(ts.sym.fields[i].type, ts.sym.fields[i]).copy();
         }
diff --git a/gcc/d/dmd/dcast.d b/gcc/d/dmd/dcast.d
index ba3afb7716d..02bf6cf3495 100644
--- a/gcc/d/dmd/dcast.d
+++ b/gcc/d/dmd/dcast.d
@@ -192,7 +192,7 @@ Expression implicitCastTo(Expression e, Scope* sc, Type t)
             {
                 Type tb = t.toBasetype();
                 Type tx = (tb.ty == Tsarray)
-                    ? tb.nextOf().sarrayOf(ale.elements ? ale.elements.dim : 0)
+                    ? tb.nextOf().sarrayOf(ale.elements ? ale.elements.length : 0)
                     : tb.nextOf().arrayOf();
                 se.e1 = ale.implicitCastTo(sc, tx);
             }
@@ -333,7 +333,7 @@ MATCH implicitConvTo(Expression e, Type t)
     {
         const size_t nparams = tf.parameterList.length;
         const size_t j = tf.isDstyleVariadic(); // if TypeInfoArray was prepended
-        foreach (const i; j .. args.dim)
+        foreach (const i; j .. args.length)
         {
             Expression earg = (*args)[i];
             Type targ = earg.type.toBasetype();
@@ -749,12 +749,12 @@ MATCH implicitConvTo(Expression e, Type t)
 
             if (auto tsa = tb.isTypeSArray())
             {
-                if (e.elements.dim != tsa.dim.toInteger())
+                if (e.elements.length != tsa.dim.toInteger())
                     result = MATCH.nomatch;
             }
 
             Type telement = tb.nextOf();
-            if (!e.elements.dim)
+            if (!e.elements.length)
             {
                 if (typen.ty != Tvoid)
                     result = typen.implicitConvTo(telement);
@@ -767,7 +767,7 @@ MATCH implicitConvTo(Expression e, Type t)
                     if (m < result)
                         result = m;
                 }
-                for (size_t i = 0; i < e.elements.dim; i++)
+                for (size_t i = 0; i < e.elements.length; i++)
                 {
                     Expression el = (*e.elements)[i];
                     if (result == MATCH.nomatch)
@@ -792,7 +792,7 @@ MATCH implicitConvTo(Expression e, Type t)
             TypeVector tv = tb.isTypeVector();
             TypeSArray tbase = tv.basetype.isTypeSArray();
             assert(tbase);
-            const edim = e.elements.dim;
+            const edim = e.elements.length;
             const tbasedim = tbase.dim.toInteger();
             if (edim > tbasedim)
             {
@@ -1233,7 +1233,7 @@ MATCH implicitConvTo(Expression e, Type t)
          */
         if (!e.member && e.arguments)
         {
-            for (size_t i = 0; i < e.arguments.dim; ++i)
+            for (size_t i = 0; i < e.arguments.length; ++i)
             {
                 Expression earg = (*e.arguments)[i];
                 if (!earg) // https://issues.dlang.org/show_bug.cgi?id=14853
@@ -1284,7 +1284,7 @@ MATCH implicitConvTo(Expression e, Type t)
                 {
                     extern (C++) static bool convertible(Expression e, ClassDeclaration cd, MOD mod)
                     {
-                        for (size_t i = 0; i < cd.fields.dim; i++)
+                        for (size_t i = 0; i < cd.fields.length; i++)
                         {
                             VarDeclaration v = cd.fields[i];
                             Initializer _init = v._init;
@@ -2101,7 +2101,7 @@ Expression castTo(Expression e, Scope* sc, Type t, Type att = null)
         {
             OverExp eo = e.e1.isOverExp();
             FuncDeclaration f = null;
-            for (size_t i = 0; i < eo.vars.a.dim; i++)
+            for (size_t i = 0; i < eo.vars.a.length; i++)
             {
                 auto s = eo.vars.a[i];
                 auto f2 = s.isFuncDeclaration();
@@ -2177,7 +2177,7 @@ Expression castTo(Expression e, Scope* sc, Type t, Type att = null)
         TupleExp te = e.copy().isTupleExp();
         te.e0 = e.e0 ? e.e0.copy() : null;
         te.exps = e.exps.copy();
-        for (size_t i = 0; i < te.exps.dim; i++)
+        for (size_t i = 0; i < te.exps.length; i++)
         {
             Expression ex = (*te.exps)[i];
             ex = ex.castTo(sc, totuple ? (*totuple.arguments)[i].type : t);
@@ -2239,7 +2239,7 @@ Expression castTo(Expression e, Scope* sc, Type t, Type att = null)
             {
                 if (auto tsa = tb.isTypeSArray())
                 {
-                    if (e.elements.dim != tsa.dim.toInteger())
+                    if (e.elements.length != tsa.dim.toInteger())
                         goto L1;
                 }
 
@@ -2247,7 +2247,7 @@ Expression castTo(Expression e, Scope* sc, Type t, Type att = null)
                 if (e.basis)
                     ae.basis = e.basis.castTo(sc, tb.nextOf());
                 ae.elements = e.elements.copy();
-                for (size_t i = 0; i < e.elements.dim; i++)
+                for (size_t i = 0; i < e.elements.length; i++)
                 {
                     Expression ex = (*e.elements)[i];
                     if (!ex)
@@ -2274,7 +2274,7 @@ Expression castTo(Expression e, Scope* sc, Type t, Type att = null)
             TypeVector tv = tb.isTypeVector();
             TypeSArray tbase = tv.basetype.isTypeSArray();
             assert(tbase.ty == Tsarray);
-            const edim = e.elements.dim;
+            const edim = e.elements.length;
             const tbasedim = tbase.dim.toInteger();
             if (edim > tbasedim)
                 goto L1;
@@ -2322,8 +2322,8 @@ Expression castTo(Expression e, Scope* sc, Type t, Type att = null)
             AssocArrayLiteralExp ae = e.copy().isAssocArrayLiteralExp();
             ae.keys = e.keys.copy();
             ae.values = e.values.copy();
-            assert(e.keys.dim == e.values.dim);
-            for (size_t i = 0; i < e.keys.dim; i++)
+            assert(e.keys.length == e.values.length);
+            for (size_t i = 0; i < e.keys.length; i++)
             {
                 Expression ex = (*e.values)[i];
                 ex = ex.castTo(sc, tb.nextOf());
@@ -2637,7 +2637,7 @@ Expression inferType(Expression e, Type t, int flag = 0)
             Type tn = tb.nextOf();
             if (ale.basis)
                 ale.basis = inferType(ale.basis, tn, flag);
-            for (size_t i = 0; i < ale.elements.dim; i++)
+            for (size_t i = 0; i < ale.elements.length; i++)
             {
                 if (Expression e = (*ale.elements)[i])
                 {
@@ -2656,7 +2656,7 @@ Expression inferType(Expression e, Type t, int flag = 0)
         {
             Type ti = taa.index;
             Type tv = taa.nextOf();
-            for (size_t i = 0; i < aale.keys.dim; i++)
+            for (size_t i = 0; i < aale.keys.length; i++)
             {
                 if (Expression e = (*aale.keys)[i])
                 {
@@ -2664,7 +2664,7 @@ Expression inferType(Expression e, Type t, int flag = 0)
                     (*aale.keys)[i] = e;
                 }
             }
-            for (size_t i = 0; i < aale.values.dim; i++)
+            for (size_t i = 0; i < aale.values.length; i++)
             {
                 if (Expression e = (*aale.values)[i])
                 {
@@ -2772,7 +2772,7 @@ Expression scaleFactor(BinExp be, Scope* sc)
  */
 private bool isVoidArrayLiteral(Expression e, Type other)
 {
-    while (e.op == EXP.arrayLiteral && e.type.ty == Tarray && (e.isArrayLiteralExp().elements.dim == 1))
+    while (e.op == EXP.arrayLiteral && e.type.ty == Tarray && (e.isArrayLiteralExp().elements.length == 1))
     {
         auto ale = e.isArrayLiteralExp();
         e = ale[0];
@@ -2784,7 +2784,7 @@ private bool isVoidArrayLiteral(Expression e, Type other)
     if (other.ty != Tsarray && other.ty != Tarray)
         return false;
     Type t = e.type;
-    return (e.op == EXP.arrayLiteral && t.ty == Tarray && t.nextOf().ty == Tvoid && e.isArrayLiteralExp().elements.dim == 0);
+    return (e.op == EXP.arrayLiteral && t.ty == Tarray && t.nextOf().ty == Tvoid && e.isArrayLiteralExp().elements.length == 0);
 }
 
 /**
diff --git a/gcc/d/dmd/dclass.d b/gcc/d/dmd/dclass.d
index a4a2abf4144..fc49b210480 100644
--- a/gcc/d/dmd/dclass.d
+++ b/gcc/d/dmd/dclass.d
@@ -74,10 +74,10 @@ extern (C++) struct BaseClass
 
         //printf("BaseClass.fillVtbl(this='%s', cd='%s')\n", sym.toChars(), cd.toChars());
         if (vtbl)
-            vtbl.setDim(sym.vtbl.dim);
+            vtbl.setDim(sym.vtbl.length);
 
         // first entry is ClassInfo reference
-        for (size_t j = sym.vtblOffset(); j < sym.vtbl.dim; j++)
+        for (size_t j = sym.vtblOffset(); j < sym.vtbl.length; j++)
         {
             FuncDeclaration ifd = sym.vtbl[j].isFuncDeclaration();
 
@@ -113,7 +113,7 @@ extern (C++) struct BaseClass
             BaseClass* b = &baseInterfaces[i];
             BaseClass* b2 = sym.interfaces[i];
 
-            assert(b2.vtbl.dim == 0); // should not be filled yet
+            assert(b2.vtbl.length == 0); // should not be filled yet
             memcpy(b, b2, BaseClass.sizeof);
 
             if (i) // single inheritance is i==0
@@ -217,7 +217,7 @@ extern (C++) class ClassDeclaration : AggregateDeclaration
 
         this.members = members;
 
-        //printf("ClassDeclaration(%s), dim = %d\n", ident.toChars(), this.baseclasses.dim);
+        //printf("ClassDeclaration(%s), dim = %d\n", ident.toChars(), this.baseclasses.length);
 
         // For forward references
         type = new TypeClass(this);
@@ -390,8 +390,8 @@ extern (C++) class ClassDeclaration : AggregateDeclaration
 
         cd.storage_class |= storage_class;
 
-        cd.baseclasses.setDim(this.baseclasses.dim);
-        for (size_t i = 0; i < cd.baseclasses.dim; i++)
+        cd.baseclasses.setDim(this.baseclasses.length);
+        for (size_t i = 0; i < cd.baseclasses.length; i++)
         {
             BaseClass* b = (*this.baseclasses)[i];
             auto b2 = new BaseClass(b.type.syntaxCopy());
@@ -424,7 +424,7 @@ extern (C++) class ClassDeclaration : AggregateDeclaration
         if (!cd)
             return false;
         //printf("ClassDeclaration.isBaseOf2(this = '%s', cd = '%s')\n", toChars(), cd.toChars());
-        for (size_t i = 0; i < cd.baseclasses.dim; i++)
+        for (size_t i = 0; i < cd.baseclasses.length; i++)
         {
             BaseClass* b = (*cd.baseclasses)[i];
             if (b.sym == this || isBaseOf2(b.sym))
@@ -610,7 +610,7 @@ extern (C++) class ClassDeclaration : AggregateDeclaration
                 if (!b.sym.alignsize)
                     b.sym.alignsize = target.ptrsize;
                 alignmember(structalign_t(cast(ushort)b.sym.alignsize), b.sym.alignsize, &offset);
-                assert(bi < vtblInterfaces.dim);
+                assert(bi < vtblInterfaces.length);
 
                 BaseClass* bv = (*vtblInterfaces)[bi];
                 if (b.sym.interfaces.length == 0)
@@ -879,7 +879,7 @@ extern (C++) class ClassDeclaration : AggregateDeclaration
             return 0;
         }
 
-        for (size_t i = 0; i < members.dim; i++)
+        for (size_t i = 0; i < members.length; i++)
         {
             auto s = (*members)[i];
             if (s.apply(&func))
@@ -917,7 +917,7 @@ extern (C++) class ClassDeclaration : AggregateDeclaration
                 return 0;
             }
 
-            for (size_t i = 0; i < members.dim; i++)
+            for (size_t i = 0; i < members.length; i++)
             {
                 auto s = (*members)[i];
                 s.apply(&virtualSemantic);
@@ -926,7 +926,7 @@ extern (C++) class ClassDeclaration : AggregateDeclaration
 
         /* Finally, check the vtbl[]
          */
-        foreach (i; 1 .. vtbl.dim)
+        foreach (i; 1 .. vtbl.length)
         {
             auto fd = vtbl[i].isFuncDeclaration();
             //if (fd) printf("\tvtbl[%d] = [%s] %s\n", i, fd.loc.toChars(), fd.toPrettyChars());
@@ -980,7 +980,7 @@ extern (C++) class ClassDeclaration : AggregateDeclaration
     {
         if (!vtblsym)
         {
-            auto vtype = Type.tvoidptr.immutableOf().sarrayOf(vtbl.dim);
+            auto vtype = Type.tvoidptr.immutableOf().sarrayOf(vtbl.length);
             auto var = new VarDeclaration(loc, vtype, Identifier.idPool("__vtbl"), null, STC.immutable_ | STC.static_);
             var.addMember(null, this);
             var.isdataseg = 1;
@@ -991,6 +991,11 @@ extern (C++) class ClassDeclaration : AggregateDeclaration
         return vtblsym;
     }
 
+    extern (D) final bool isErrorException()
+    {
+        return errorException && (this == errorException || errorException.isBaseOf(this, null));
+    }
+
     override final inout(ClassDeclaration) isClassDeclaration() inout @nogc nothrow pure @safe
     {
         return this;
diff --git a/gcc/d/dmd/declaration.d b/gcc/d/dmd/declaration.d
index 07d58f047c3..3d0752c1d8b 100644
--- a/gcc/d/dmd/declaration.d
+++ b/gcc/d/dmd/declaration.d
@@ -66,7 +66,7 @@ bool checkFrameAccess(Loc loc, Scope* sc, AggregateDeclaration ad, size_t iStart
     }
 
     bool result = false;
-    for (size_t i = iStart; i < ad.fields.dim; i++)
+    for (size_t i = iStart; i < ad.fields.length; i++)
     {
         VarDeclaration vd = ad.fields[i];
         Type tb = vd.type.baseElemOf();
@@ -297,7 +297,7 @@ extern (C++) abstract class Declaration : Dsymbol
                 {
                     auto sd = p.isStructDeclaration();
                     assert(sd);
-                    for (size_t i = 0; i < sd.fields.dim; i++)
+                    for (size_t i = 0; i < sd.fields.length; i++)
                     {
                         auto structField = sd.fields[i];
                         if (structField.overlapped)
@@ -606,7 +606,7 @@ extern (C++) final class TupleDeclaration : Declaration
         {
             /* It's only a type tuple if all the Object's are types
              */
-            for (size_t i = 0; i < objects.dim; i++)
+            for (size_t i = 0; i < objects.length; i++)
             {
                 RootObject o = (*objects)[i];
                 if (o.dyncast() != DYNCAST.type)
@@ -619,10 +619,10 @@ extern (C++) final class TupleDeclaration : Declaration
             /* We know it's a type tuple, so build the TypeTuple
              */
             Types* types = cast(Types*)objects;
-            auto args = new Parameters(objects.dim);
+            auto args = new Parameters(objects.length);
             OutBuffer buf;
             int hasdeco = 1;
-            for (size_t i = 0; i < types.dim; i++)
+            for (size_t i = 0; i < types.length; i++)
             {
                 Type t = (*types)[i];
                 //printf("type = %s\n", t.toChars());
@@ -653,7 +653,7 @@ extern (C++) final class TupleDeclaration : Declaration
     override Dsymbol toAlias2()
     {
         //printf("TupleDeclaration::toAlias2() '%s' objects = %s\n", toChars(), objects.toChars());
-        for (size_t i = 0; i < objects.dim; i++)
+        for (size_t i = 0; i < objects.length; i++)
         {
             RootObject o = (*objects)[i];
             if (Dsymbol s = isDsymbol(o))
@@ -1219,7 +1219,7 @@ extern (C++) class VarDeclaration : Declaration
             fieldState.offset = ad.structsize; // https://issues.dlang.org/show_bug.cgi?id=13613
             return;
         }
-        for (size_t i = 0; i < ad.fields.dim; i++)
+        for (size_t i = 0; i < ad.fields.length; i++)
         {
             if (ad.fields[i] == this)
             {
diff --git a/gcc/d/dmd/delegatize.d b/gcc/d/dmd/delegatize.d
index 77e09bcc573..461f44131c3 100644
--- a/gcc/d/dmd/delegatize.d
+++ b/gcc/d/dmd/delegatize.d
@@ -96,7 +96,7 @@ private void lambdaSetParent(Expression e, FuncDeclaration fd)
             if (!vd || !pfd)
                 return;
             // move to fd's closure when applicable
-            foreach (i; 0 .. pfd.closureVars.dim)
+            foreach (i; 0 .. pfd.closureVars.length)
             {
                 if (vd == pfd.closureVars[i])
                 {
diff --git a/gcc/d/dmd/denum.d b/gcc/d/dmd/denum.d
index ef322f13da5..926186bc4a8 100644
--- a/gcc/d/dmd/denum.d
+++ b/gcc/d/dmd/denum.d
@@ -88,7 +88,7 @@ extern (C++) final class EnumDeclaration : ScopeDsymbol
         version (none)
         {
             printf("EnumDeclaration::addMember() %s\n", toChars());
-            for (size_t i = 0; i < members.dim; i++)
+            for (size_t i = 0; i < members.length; i++)
             {
                 EnumMember em = (*members)[i].isEnumMember();
                 printf("    member %s\n", em.toChars());
@@ -191,7 +191,7 @@ extern (C++) final class EnumDeclaration : ScopeDsymbol
             return handleErrors();
         }
 
-        foreach (const i; 0 .. members.dim)
+        foreach (const i; 0 .. members.length)
         {
             EnumMember em = (*members)[i].isEnumMember();
             if (em)
diff --git a/gcc/d/dmd/dimport.d b/gcc/d/dmd/dimport.d
index 705acd1c98f..1104005b1ac 100644
--- a/gcc/d/dmd/dimport.d
+++ b/gcc/d/dmd/dimport.d
@@ -114,7 +114,7 @@ extern (C++) final class Import : Dsymbol
         assert(!s);
         auto si = new Import(loc, packages, id, aliasId, isstatic);
         si.comment = comment;
-        for (size_t i = 0; i < names.dim; i++)
+        for (size_t i = 0; i < names.length; i++)
         {
             si.addAlias(names[i], aliases[i]);
         }
@@ -241,11 +241,11 @@ extern (C++) final class Import : Dsymbol
         mod.checkImportDeprecation(loc, sc);
         if (sc.explicitVisibility)
             visibility = sc.visibility;
-        if (!isstatic && !aliasId && !names.dim)
+        if (!isstatic && !aliasId && !names.length)
             sc.scopesym.importScope(mod, visibility);
         // Enable access to pkgs/mod as soon as posible, because compiler
         // can traverse them before the import gets semantic (Issue: 21501)
-        if (!aliasId && !names.dim)
+        if (!aliasId && !names.length)
             addPackageAccess(sc.scopesym);
     }
 
@@ -296,14 +296,14 @@ extern (C++) final class Import : Dsymbol
     override void addMember(Scope* sc, ScopeDsymbol sd)
     {
         //printf("Import.addMember(this=%s, sd=%s, sc=%p)\n", toChars(), sd.toChars(), sc);
-        if (names.dim == 0)
+        if (names.length == 0)
             return Dsymbol.addMember(sc, sd);
         if (aliasId)
             Dsymbol.addMember(sc, sd);
         /* Instead of adding the import to sd's symbol table,
          * add each of the alias=name pairs
          */
-        for (size_t i = 0; i < names.dim; i++)
+        for (size_t i = 0; i < names.length; i++)
         {
             Identifier name = names[i];
             Identifier _alias = aliases[i];
@@ -320,7 +320,7 @@ extern (C++) final class Import : Dsymbol
     override void setScope(Scope* sc)
     {
         Dsymbol.setScope(sc);
-        if (aliasdecls.dim)
+        if (aliasdecls.length)
         {
             if (!mod)
                 importAll(sc);
diff --git a/gcc/d/dmd/dinterpret.d b/gcc/d/dmd/dinterpret.d
index 63b700096e5..e504cb4879f 100644
--- a/gcc/d/dmd/dinterpret.d
+++ b/gcc/d/dmd/dinterpret.d
@@ -282,7 +282,7 @@ private:
 public:
     extern (C++) size_t stackPointer()
     {
-        return values.dim;
+        return values.length;
     }
 
     // The current value of 'this', or NULL if none
@@ -308,12 +308,12 @@ public:
 
     extern (C++) void endFrame()
     {
-        size_t oldframe = cast(size_t)frames[frames.dim - 1];
-        localThis = savedThis[savedThis.dim - 1];
+        size_t oldframe = cast(size_t)frames[frames.length - 1];
+        localThis = savedThis[savedThis.length - 1];
         popAll(framepointer);
         framepointer = oldframe;
-        frames.setDim(frames.dim - 1);
-        savedThis.setDim(savedThis.dim - 1);
+        frames.setDim(frames.length - 1);
+        savedThis.setDim(savedThis.length - 1);
     }
 
     extern (C++) bool isInCurrentFrame(VarDeclaration v)
@@ -328,7 +328,7 @@ public:
         //printf("getValue() %s\n", v.toChars());
         if ((v.isDataseg() || v.storage_class & STC.manifest) && !v.isCTFE())
         {
-            assert(v.ctfeAdrOnStack < globalValues.dim);
+            assert(v.ctfeAdrOnStack < globalValues.length);
             return globalValues[v.ctfeAdrOnStack];
         }
         assert(v.ctfeAdrOnStack < stackPointer());
@@ -354,7 +354,7 @@ public:
             return;
         }
         savedId.push(cast(void*)cast(size_t)v.ctfeAdrOnStack);
-        v.ctfeAdrOnStack = cast(uint)values.dim;
+        v.ctfeAdrOnStack = cast(uint)values.length;
         vars.push(v);
         values.push(null);
     }
@@ -365,7 +365,7 @@ public:
         assert(!v.isReference());
         const oldid = v.ctfeAdrOnStack;
         v.ctfeAdrOnStack = cast(uint)cast(size_t)savedId[oldid];
-        if (v.ctfeAdrOnStack == values.dim - 1)
+        if (v.ctfeAdrOnStack == values.length - 1)
         {
             values.pop();
             vars.pop();
@@ -377,8 +377,8 @@ public:
     {
         if (stackPointer() > maxStackPointer)
             maxStackPointer = stackPointer();
-        assert(values.dim >= stackpointer);
-        for (size_t i = stackpointer; i < values.dim; ++i)
+        assert(values.length >= stackpointer);
+        for (size_t i = stackpointer; i < values.length; ++i)
         {
             VarDeclaration v = vars[i];
             v.ctfeAdrOnStack = cast(uint)cast(size_t)savedId[i];
@@ -391,7 +391,7 @@ public:
     extern (C++) void saveGlobalConstant(VarDeclaration v, Expression e)
     {
         assert(v._init && (v.isConst() || v.isImmutable() || v.storage_class & STC.manifest) && !v.isCTFE());
-        v.ctfeAdrOnStack = cast(uint)globalValues.dim;
+        v.ctfeAdrOnStack = cast(uint)globalValues.length;
         globalValues.push(copyRegionExp(e));
     }
 }
@@ -444,7 +444,7 @@ private Expression interpretFunction(UnionExp* pue, FuncDeclaration fd, InterSta
 
     auto tf = fd.type.toBasetype().isTypeFunction();
     if (tf.parameterList.varargs != VarArg.none && arguments &&
-        ((fd.parameters && arguments.dim != fd.parameters.dim) || (!fd.parameters && arguments.dim)))
+        ((fd.parameters && arguments.length != fd.parameters.length) || (!fd.parameters && arguments.length)))
     {
         fd.error("C-style variadic functions are not yet implemented in CTFE");
         return CTFEExp.cantexp;
@@ -467,8 +467,8 @@ private Expression interpretFunction(UnionExp* pue, FuncDeclaration fd, InterSta
 
     // Place to hold all the arguments to the function while
     // we are evaluating them.
-    size_t dim = arguments ? arguments.dim : 0;
-    assert((fd.parameters ? fd.parameters.dim : 0) == dim);
+    size_t dim = arguments ? arguments.length : 0;
+    assert((fd.parameters ? fd.parameters.length : 0) == dim);
 
     /* Evaluate all the arguments to the function,
      * store the results in eargs[]
@@ -827,7 +827,7 @@ public:
         if (istate.start == s)
             istate.start = null;
 
-        const dim = s.statements ? s.statements.dim : 0;
+        const dim = s.statements ? s.statements.length : 0;
         foreach (i; 0 .. dim)
         {
             Statement sx = (*s.statements)[i];
@@ -850,7 +850,7 @@ public:
         if (istate.start == s)
             istate.start = null;
 
-        const dim = s.statements ? s.statements.dim : 0;
+        const dim = s.statements ? s.statements.length : 0;
         foreach (i; 0 .. dim)
         {
             Statement sx = (*s.statements)[i];
@@ -1034,7 +1034,7 @@ public:
             result = interpret(pue, s.exp, istate, CTFEGoal.LValue);
             return;
         }
-        if (tf.next && tf.next.ty == Tdelegate && istate.fd.closureVars.dim > 0)
+        if (tf.next && tf.next.ty == Tdelegate && istate.fd.closureVars.length > 0)
         {
             // To support this, we need to copy all the closure vars
             // into the delegate literal.
@@ -1521,11 +1521,6 @@ public:
         result = e;
     }
 
-    static bool isAnErrorException(ClassDeclaration cd)
-    {
-        return cd == ClassDeclaration.errorException || ClassDeclaration.errorException.isBaseOf(cd, null);
-    }
-
     static ThrownExceptionExp chainExceptions(ThrownExceptionExp oldest, ThrownExceptionExp newest)
     {
         debug (LOG)
@@ -1537,7 +1532,7 @@ public:
         const next = 4;                         // index of Throwable.next
         assert((*boss.value.elements)[next].type.ty == Tclass); // Throwable.next
         ClassReferenceExp collateral = newest.thrown;
-        if (isAnErrorException(collateral.originalClass()) && !isAnErrorException(boss.originalClass()))
+        if (collateral.originalClass().isErrorException() && !boss.originalClass().isErrorException())
         {
             /* Find the index of the Error.bypassException field
              */
@@ -1647,8 +1642,15 @@ public:
         if (exceptionOrCant(e))
             return;
 
-        assert(e.op == EXP.classReference);
-        result = ctfeEmplaceExp!ThrownExceptionExp(loc, e.isClassReferenceExp());
+        if (e.op == EXP.classReference)
+        {
+            result = ctfeEmplaceExp!ThrownExceptionExp(loc, e.isClassReferenceExp());
+        }
+        else
+        {
+            exp.error("to be thrown `%s` must be non-null", exp.toChars());
+            result = ErrorExp.get();
+        }
     }
 
     override void visit(ScopeGuardStatement s)
@@ -2296,7 +2298,7 @@ public:
         while (s.isAttribDeclaration())
         {
             auto ad = cast(AttribDeclaration)s;
-            assert(ad.decl && ad.decl.dim == 1); // Currently, only one allowed when parsing
+            assert(ad.decl && ad.decl.length == 1); // Currently, only one allowed when parsing
             s = (*ad.decl)[0];
         }
         if (VarDeclaration v = s.isVarDeclaration())
@@ -2505,7 +2507,7 @@ public:
             return;
 
         auto expsx = e.elements;
-        size_t dim = expsx ? expsx.dim : 0;
+        size_t dim = expsx ? expsx.length : 0;
         for (size_t i = 0; i < dim; i++)
         {
             Expression exp = (*expsx)[i];
@@ -2544,7 +2546,7 @@ public:
         {
             // todo: all tuple expansions should go in semantic phase.
             expandTuples(expsx);
-            if (expsx.dim != dim)
+            if (expsx.length != dim)
             {
                 e.error("CTFE internal error: invalid array literal");
                 result = CTFEExp.cantexp;
@@ -2607,7 +2609,7 @@ public:
             expandTuples(keysx);
         if (valuesx !is e.values)
             expandTuples(valuesx);
-        if (keysx.dim != valuesx.dim)
+        if (keysx.length != valuesx.length)
         {
             e.error("CTFE internal error: invalid AA");
             result = CTFEExp.cantexp;
@@ -2616,10 +2618,10 @@ public:
 
         /* Remove duplicate keys
          */
-        for (size_t i = 1; i < keysx.dim; i++)
+        for (size_t i = 1; i < keysx.length; i++)
         {
             auto ekey = (*keysx)[i - 1];
-            for (size_t j = i; j < keysx.dim; j++)
+            for (size_t j = i; j < keysx.length; j++)
             {
                 auto ekey2 = (*keysx)[j];
                 if (!ctfeEqual(e.loc, EXP.equal, ekey, ekey2))
@@ -2665,14 +2667,14 @@ public:
             return;
         }
 
-        size_t dim = e.elements ? e.elements.dim : 0;
+        size_t dim = e.elements ? e.elements.length : 0;
         auto expsx = e.elements;
 
-        if (dim != e.sd.fields.dim)
+        if (dim != e.sd.fields.length)
         {
             // guaranteed by AggregateDeclaration.fill and TypeStruct.defaultInitLiteral
-            const nvthis = e.sd.fields.dim - e.sd.nonHiddenFields();
-            assert(e.sd.fields.dim - dim == nvthis);
+            const nvthis = e.sd.fields.length - e.sd.nonHiddenFields();
+            assert(e.sd.fields.length - dim == nvthis);
 
             /* If a nested struct has no initialized hidden pointer,
              * set it to null to match the runtime behaviour.
@@ -2688,7 +2690,7 @@ public:
                 ++dim;
             }
         }
-        assert(dim == e.sd.fields.dim);
+        assert(dim == e.sd.fields.length);
 
         foreach (i; 0 .. dim)
         {
@@ -2728,7 +2730,7 @@ public:
         if (expsx !is e.elements)
         {
             expandTuples(expsx);
-            if (expsx.dim != e.sd.fields.dim)
+            if (expsx.length != e.sd.fields.length)
             {
                 e.error("CTFE internal error: invalid struct literal");
                 result = CTFEExp.cantexp;
@@ -2757,7 +2759,7 @@ public:
             return lenExpr;
         size_t len = cast(size_t)lenExpr.toInteger();
         Type elemType = (cast(TypeArray)newtype).next;
-        if (elemType.ty == Tarray && argnum < arguments.dim - 1)
+        if (elemType.ty == Tarray && argnum < arguments.length - 1)
         {
             Expression elem = recursivelyCreateArrayLiteral(pue, loc, elemType, istate, arguments, argnum + 1);
             if (exceptionOrCantInterpret(elem))
@@ -2771,7 +2773,7 @@ public:
             ae.ownedByCtfe = OwnedBy.ctfe;
             return ae;
         }
-        assert(argnum == arguments.dim - 1);
+        assert(argnum == arguments.length - 1);
         if (elemType.ty.isSomeChar)
         {
             const ch = cast(dchar)elemType.defaultInitLiteral(loc).toInteger();
@@ -2818,10 +2820,10 @@ public:
             {
                 StructDeclaration sd = ts.sym;
                 auto exps = new Expressions();
-                exps.reserve(sd.fields.dim);
+                exps.reserve(sd.fields.length);
                 if (e.arguments)
                 {
-                    exps.setDim(e.arguments.dim);
+                    exps.setDim(e.arguments.length);
                     foreach (i, ex; *e.arguments)
                     {
                         ex = interpretRegion(ex, istate);
@@ -2850,12 +2852,12 @@ public:
             ClassDeclaration cd = tc.sym;
             size_t totalFieldCount = 0;
             for (ClassDeclaration c = cd; c; c = c.baseClass)
-                totalFieldCount += c.fields.dim;
+                totalFieldCount += c.fields.length;
             auto elems = new Expressions(totalFieldCount);
             size_t fieldsSoFar = totalFieldCount;
             for (ClassDeclaration c = cd; c; c = c.baseClass)
             {
-                fieldsSoFar -= c.fields.dim;
+                fieldsSoFar -= c.fields.length;
                 foreach (i, v; c.fields)
                 {
                     if (v.inuse)
@@ -2927,7 +2929,7 @@ public:
         if (e.newtype.toBasetype().isscalar())
         {
             Expression newval;
-            if (e.arguments && e.arguments.dim)
+            if (e.arguments && e.arguments.length)
                 newval = (*e.arguments)[0];
             else
                 newval = e.newtype.defaultInitLiteral(e.loc);
@@ -3850,7 +3852,7 @@ public:
                 e.error("CTFE internal error: cannot find field `%s` in `%s`", v.toChars(), ex.toChars());
                 return CTFEExp.cantexp;
             }
-            assert(0 <= fieldi && fieldi < sle.elements.dim);
+            assert(0 <= fieldi && fieldi < sle.elements.length);
 
             // If it's a union, set all other members of this union to void
             stompOverlappedFields(sle, v);
@@ -3958,7 +3960,7 @@ public:
 
             Expressions* oldelems = oldval.isArrayLiteralExp().elements;
             Expressions* newelems = newval.isArrayLiteralExp().elements;
-            assert(oldelems.dim == newelems.dim);
+            assert(oldelems.length == newelems.length);
 
             Type elemtype = oldval.type.nextOf();
             foreach (i, ref oldelem; *oldelems)
@@ -4049,7 +4051,7 @@ public:
             if (auto ale = e1.isArrayLiteralExp())
             {
                 lowerbound = 0;
-                upperbound = ale.elements.dim;
+                upperbound = ale.elements.length;
             }
             else if (auto se = e1.isStringExp())
             {
@@ -4287,7 +4289,7 @@ public:
 
                 extern (C++) Expression assignTo(ArrayLiteralExp ae)
                 {
-                    return assignTo(ae, 0, ae.elements.dim);
+                    return assignTo(ae, 0, ae.elements.length);
                 }
 
                 extern (C++) Expression assignTo(ArrayLiteralExp ae, size_t lwr, size_t upr)
@@ -4786,7 +4788,7 @@ public:
 
             if (fd.ident == Id.__ArrayPostblit || fd.ident == Id.__ArrayDtor)
             {
-                assert(e.arguments.dim == 1);
+                assert(e.arguments.length == 1);
                 Expression ea = (*e.arguments)[0];
                 // printf("1 ea = %s %s\n", ea.type.toChars(), ea.toChars());
                 if (auto se = ea.isSliceExp())
@@ -4822,7 +4824,7 @@ public:
             {
                 // In expressionsem.d `ea.length = eb;` got lowered to `_d_arraysetlengthT(ea, eb);`.
                 // The following code will rewrite it back to `ea.length = eb` and then interpret that expression.
-                assert(e.arguments.dim == 2);
+                assert(e.arguments.length == 2);
 
                 Expression ea = (*e.arguments)[0];
                 Expression eb = (*e.arguments)[1];
@@ -4846,9 +4848,9 @@ public:
                 // then interpret that expression.
 
                 if (fd.ident == Id._d_arrayctor)
-                    assert(e.arguments.dim == 3);
+                    assert(e.arguments.length == 3);
                 else
-                    assert(e.arguments.dim == 2);
+                    assert(e.arguments.length == 2);
 
                 Expression ea = (*e.arguments)[0];
                 if (ea.isCastExp)
@@ -4877,13 +4879,13 @@ public:
 
                 if (fd.ident == Id._d_arrayappendT)
                 {
-                    assert(e.arguments.dim == 2);
+                    assert(e.arguments.length == 2);
                     lhs = (*e.arguments)[0];
                     rhs = (*e.arguments)[1];
                 }
                 else
                 {
-                    assert(e.arguments.dim == 5);
+                    assert(e.arguments.length == 5);
                     lhs = (*e.arguments)[3];
                     rhs = (*e.arguments)[4];
                 }
@@ -5044,7 +5046,7 @@ public:
             // `_d_arrayappendcTX(arr, elem), arr[arr.length - 1] = elem, elem;`.
             // The following code will rewrite it back to `arr ~= elem`
             // and then interpret that expression.
-            assert(ce.arguments.dim == 2);
+            assert(ce.arguments.length == 2);
 
             auto arr = (*ce.arguments)[0];
             auto elem = e.e2.isConstructExp().e2;
@@ -5999,7 +6001,7 @@ public:
                     {
                         ArrayLiteralExp ale = ie.e1.isArrayLiteralExp();
                         const indx = cast(size_t)ie.e2.toInteger();
-                        if (indx < ale.elements.dim)
+                        if (indx < ale.elements.length)
                         {
                             if (Expression xx = (*ale.elements)[indx])
                             {
@@ -6463,8 +6465,8 @@ public:
                 (*valuesx)[j - removed] = evalue;
             }
         }
-        valuesx.dim = valuesx.dim - removed;
-        keysx.dim = keysx.dim - removed;
+        valuesx.length = valuesx.length - removed;
+        keysx.length = keysx.length - removed;
         result = IntegerExp.createBool(removed != 0);
     }
 
@@ -6978,7 +6980,7 @@ private Expression interpret_length(UnionExp* pue, InterState* istate, Expressio
         return earg;
     dinteger_t len = 0;
     if (auto aae = earg.isAssocArrayLiteralExp())
-        len = aae.keys.dim;
+        len = aae.keys.length;
     else
         assert(earg.op == EXP.null_);
     emplaceExp!(IntegerExp)(pue, earg.loc, len, Type.tsize_t);
@@ -7049,7 +7051,7 @@ private Expression interpret_dup(UnionExp* pue, InterState* istate, Expression e
     if (earg.op != EXP.assocArrayLiteral && earg.type.toBasetype().ty != Taarray)
         return null;
     auto aae = copyLiteral(earg).copy().isAssocArrayLiteralExp();
-    for (size_t i = 0; i < aae.keys.dim; i++)
+    for (size_t i = 0; i < aae.keys.length; i++)
     {
         if (Expression e = evaluatePostblit(istate, (*aae.keys)[i]))
             return e;
@@ -7085,7 +7087,7 @@ private Expression interpret_aaApply(UnionExp* pue, InterState* istate, Expressi
 
     assert(fd && fd.fbody);
     assert(fd.parameters);
-    size_t numParams = fd.parameters.dim;
+    size_t numParams = fd.parameters.length;
     assert(numParams == 1 || numParams == 2);
 
     Parameter fparam = fd.type.isTypeFunction().parameterList[numParams - 1];
@@ -7094,11 +7096,11 @@ private Expression interpret_aaApply(UnionExp* pue, InterState* istate, Expressi
     Expressions args = Expressions(numParams);
 
     AssocArrayLiteralExp ae = aa.isAssocArrayLiteralExp();
-    if (!ae.keys || ae.keys.dim == 0)
+    if (!ae.keys || ae.keys.length == 0)
         return ctfeEmplaceExp!IntegerExp(deleg.loc, 0, Type.tsize_t);
     Expression eresult;
 
-    for (size_t i = 0; i < ae.keys.dim; ++i)
+    for (size_t i = 0; i < ae.keys.length; ++i)
     {
         Expression ekey = (*ae.keys)[i];
         Expression evalue = (*ae.values)[i];
@@ -7146,7 +7148,7 @@ private Expression foreachApplyUtf(UnionExp* pue, InterState* istate, Expression
 
     assert(fd && fd.fbody);
     assert(fd.parameters);
-    size_t numParams = fd.parameters.dim;
+    size_t numParams = fd.parameters.length;
     assert(numParams == 1 || numParams == 2);
     Type charType = (*fd.parameters)[numParams - 1].type;
     Type indexType = numParams == 2 ? (*fd.parameters)[0].type : Type.tsize_t;
@@ -7389,7 +7391,7 @@ private Expression foreachApplyUtf(UnionExp* pue, InterState* istate, Expression
 private Expression evaluateIfBuiltin(UnionExp* pue, InterState* istate, const ref Loc loc, FuncDeclaration fd, Expressions* arguments, Expression pthis)
 {
     Expression e = null;
-    size_t nargs = arguments ? arguments.dim : 0;
+    size_t nargs = arguments ? arguments.length : 0;
     if (!pthis)
     {
         if (isBuiltin(fd) != BUILTIN.unimp)
@@ -7453,7 +7455,7 @@ private Expression evaluateIfBuiltin(UnionExp* pue, InterState* istate, const re
             // At present, the constructors just copy their arguments into the struct.
             // But we might need some magic if stack tracing gets added to druntime.
             StructLiteralExp se = pthis.isClassReferenceExp().value;
-            assert(arguments.dim <= se.elements.dim);
+            assert(arguments.length <= se.elements.length);
             foreach (i, arg; *arguments)
             {
                 auto elem = interpret(arg, istate);
@@ -7615,7 +7617,7 @@ private void removeHookTraceImpl(ref CallExp ce, ref FuncDeclaration fd)
 
     // Remove the first three trace parameters
     auto arguments = new Expressions();
-    arguments.reserve(ce.arguments.dim - 3);
+    arguments.reserve(ce.arguments.length - 3);
     arguments.pushSlice((*ce.arguments)[3 .. $]);
 
     ce = ctfeEmplaceExp!CallExp(ce.loc, ctfeEmplaceExp!VarExp(ce.loc, fd, false), arguments);
diff --git a/gcc/d/dmd/dmangle.d b/gcc/d/dmd/dmangle.d
index be0cbccc7c6..6ecaa5235f2 100644
--- a/gcc/d/dmd/dmangle.d
+++ b/gcc/d/dmd/dmangle.d
@@ -721,8 +721,8 @@ public:
         mangleIdentifier(tempdecl.ident, tempdecl);
 
         auto args = ti.tiargs;
-        size_t nparams = tempdecl.parameters.dim - (tempdecl.isVariadic() ? 1 : 0);
-        for (size_t i = 0; i < args.dim; i++)
+        size_t nparams = tempdecl.parameters.length - (tempdecl.isVariadic() ? 1 : 0);
+        for (size_t i = 0; i < args.length; i++)
         {
             auto o = (*args)[i];
             Type ta = isType(o);
@@ -814,7 +814,7 @@ public:
             }
             else if (va)
             {
-                assert(i + 1 == args.dim); // must be last one
+                assert(i + 1 == args.length); // must be last one
                 args = &va.objects;
                 i = -cast(size_t)1;
             }
@@ -960,7 +960,7 @@ public:
 
     override void visit(ArrayLiteralExp e)
     {
-        const dim = e.elements ? e.elements.dim : 0;
+        const dim = e.elements ? e.elements.length : 0;
         buf.writeByte('A');
         buf.print(dim);
         foreach (i; 0 .. dim)
@@ -971,7 +971,7 @@ public:
 
     override void visit(AssocArrayLiteralExp e)
     {
-        const dim = e.keys.dim;
+        const dim = e.keys.length;
         buf.writeByte('A');
         buf.print(dim);
         foreach (i; 0 .. dim)
@@ -983,7 +983,7 @@ public:
 
     override void visit(StructLiteralExp e)
     {
-        const dim = e.elements ? e.elements.dim : 0;
+        const dim = e.elements ? e.elements.length : 0;
         buf.writeByte('S');
         buf.print(dim);
         foreach (i; 0 .. dim)
diff --git a/gcc/d/dmd/dmodule.d b/gcc/d/dmd/dmodule.d
index b2908ce02b0..616080566d8 100644
--- a/gcc/d/dmd/dmodule.d
+++ b/gcc/d/dmd/dmodule.d
@@ -62,7 +62,7 @@ void semantic3OnDependencies(Module m)
 
     m.semantic3(null);
 
-    foreach (i; 1 .. m.aimports.dim)
+    foreach (i; 1 .. m.aimports.length)
         semantic3OnDependencies(m.aimports[i]);
 }
 
@@ -132,7 +132,7 @@ private const(char)[] getFilename(Identifier[] packages, Identifier ident) nothr
     {
         const p = pid.toString();
         buf.writestring(p);
-        if (modAliases.dim)
+        if (modAliases.length)
             checkModFileAlias(p);
         version (Windows)
             enum FileSeparator = '\\';
@@ -141,7 +141,7 @@ private const(char)[] getFilename(Identifier[] packages, Identifier ident) nothr
         buf.writeByte(FileSeparator);
     }
     buf.writestring(filename);
-    if (modAliases.dim)
+    if (modAliases.length)
         checkModFileAlias(filename);
     buf.writeByte(0);
     filename = buf.extractSlice()[0 .. $ - 1];
@@ -499,7 +499,7 @@ extern (C++) final class Module : Package
 
     extern (D) static const(char)[] find(const(char)[] filename)
     {
-        return FileManager.lookForSourceFile(filename, global.path ? (*global.path)[] : null);
+        return global.fileManager.lookForSourceFile(filename, global.path ? (*global.path)[] : null);
     }
 
     extern (C++) static Module load(const ref Loc loc, Identifiers* packages, Identifier ident)
@@ -942,7 +942,7 @@ extern (C++) final class Module : Package
         //    classinst == classinst -> .object.opEquals(classinst, classinst)
         // would fail inside object.d.
         if (filetype != FileType.c &&
-            (members.dim == 0 ||
+            (members.length == 0 ||
              (*members)[0].ident != Id.object ||
              (*members)[0].isImport() is null))
         {
@@ -953,7 +953,7 @@ extern (C++) final class Module : Package
         {
             // Add all symbols into module's symbol table
             symtab = new DsymbolTable();
-            for (size_t i = 0; i < members.dim; i++)
+            for (size_t i = 0; i < members.length; i++)
             {
                 Dsymbol s = (*members)[i];
                 s.addMember(sc, sc.scopesym);
@@ -966,12 +966,12 @@ extern (C++) final class Module : Package
          * before any semantic() on any of them.
          */
         setScope(sc); // remember module scope for semantic
-        for (size_t i = 0; i < members.dim; i++)
+        for (size_t i = 0; i < members.length; i++)
         {
             Dsymbol s = (*members)[i];
             s.setScope(sc);
         }
-        for (size_t i = 0; i < members.dim; i++)
+        for (size_t i = 0; i < members.length; i++)
         {
             Dsymbol s = (*members)[i];
             s.importAll(sc);
@@ -1115,13 +1115,13 @@ extern (C++) final class Module : Package
         __gshared int nested;
         if (nested)
             return;
-        //if (deferred.dim) printf("+Module::runDeferredSemantic(), len = %ld\n", deferred.dim);
+        //if (deferred.length) printf("+Module::runDeferredSemantic(), len = %ld\n", deferred.length);
         nested++;
 
         size_t len;
         do
         {
-            len = deferred.dim;
+            len = deferred.length;
             if (!len)
                 break;
 
@@ -1146,13 +1146,13 @@ extern (C++) final class Module : Package
                 s.dsymbolSemantic(null);
                 //printf("deferred: %s, parent = %s\n", s.toChars(), s.parent.toChars());
             }
-            //printf("\tdeferred.dim = %ld, len = %ld\n", deferred.dim, len);
+            //printf("\tdeferred.length = %ld, len = %ld\n", deferred.length, len);
             if (todoalloc)
                 free(todoalloc);
         }
-        while (deferred.dim != len); // while making progress
+        while (deferred.length != len); // while making progress
         nested--;
-        //printf("-Module::runDeferredSemantic(), len = %ld\n", deferred.dim);
+        //printf("-Module::runDeferredSemantic(), len = %ld\n", deferred.length);
     }
 
     static void runDeferredSemantic2()
@@ -1160,7 +1160,7 @@ extern (C++) final class Module : Package
         Module.runDeferredSemantic();
 
         Dsymbols* a = &Module.deferred2;
-        for (size_t i = 0; i < a.dim; i++)
+        for (size_t i = 0; i < a.length; i++)
         {
             Dsymbol s = (*a)[i];
             //printf("[%d] %s semantic2a\n", i, s.toPrettyChars());
@@ -1177,7 +1177,7 @@ extern (C++) final class Module : Package
         Module.runDeferredSemantic2();
 
         Dsymbols* a = &Module.deferred3;
-        for (size_t i = 0; i < a.dim; i++)
+        for (size_t i = 0; i < a.length; i++)
         {
             Dsymbol s = (*a)[i];
             //printf("[%d] %s semantic3a\n", i, s.toPrettyChars());
diff --git a/gcc/d/dmd/doc.d b/gcc/d/dmd/doc.d
index e1d589769fe..c04409c4d3f 100644
--- a/gcc/d/dmd/doc.d
+++ b/gcc/d/dmd/doc.d
@@ -106,7 +106,7 @@ private class Section
 
     void write(Loc loc, DocComment* dc, Scope* sc, Dsymbols* a, OutBuffer* buf)
     {
-        assert(a.dim);
+        assert(a.length);
         if (name.length)
         {
             static immutable table =
@@ -161,7 +161,7 @@ private final class ParamSection : Section
 {
     override void write(Loc loc, DocComment* dc, Scope* sc, Dsymbols* a, OutBuffer* buf)
     {
-        assert(a.dim);
+        assert(a.length);
         Dsymbol s = (*a)[0]; // test
         const(char)* p = body_.ptr;
         size_t len = body_.length;
@@ -295,10 +295,10 @@ private final class ParamSection : Section
             goto L1;
         // write out last one
         buf.writestring(")");
-        TypeFunction tf = a.dim == 1 ? isTypeFunction(s) : null;
+        TypeFunction tf = a.length == 1 ? isTypeFunction(s) : null;
         if (tf)
         {
-            size_t pcount = (tf.parameterList.parameters ? tf.parameterList.parameters.dim : 0) +
+            size_t pcount = (tf.parameterList.parameters ? tf.parameterList.parameters.length : 0) +
                             cast(int)(tf.parameterList.varargs == VarArg.variadic);
             if (pcount != paramcount)
             {
@@ -386,7 +386,7 @@ extern(C++) void gendocfile(Module m)
         if (p)
             global.params.ddoc.files.shift(p);
         // Override with the ddoc macro files from the command line
-        for (size_t i = 0; i < global.params.ddoc.files.dim; i++)
+        for (size_t i = 0; i < global.params.ddoc.files.length; i++)
         {
             auto buffer = readFile(m.loc, global.params.ddoc.files[i]);
             // BUG: convert file contents to UTF-8 before use
@@ -757,9 +757,9 @@ private void emitAnchor(ref OutBuffer buf, Dsymbol s, Scope* sc, bool forHeader
     if (auto imp = s.isImport())
     {
         // For example: `public import core.stdc.string : memcpy, memcmp;`
-        if (imp.aliases.dim > 0)
+        if (imp.aliases.length > 0)
         {
-            for(int i = 0; i < imp.aliases.dim; i++)
+            for(int i = 0; i < imp.aliases.length; i++)
             {
                 // Need to distinguish between
                 // `public import core.stdc.string : memcpy, memcmp;` and
@@ -866,7 +866,7 @@ private void expandTemplateMixinComments(TemplateMixin tm, ref OutBuffer buf, Sc
     TemplateDeclaration td = (tm && tm.tempdecl) ? tm.tempdecl.isTemplateDeclaration() : null;
     if (td && td.members)
     {
-        for (size_t i = 0; i < td.members.dim; i++)
+        for (size_t i = 0; i < td.members.length; i++)
         {
             Dsymbol sm = (*td.members)[i];
             TemplateMixin tmc = sm.isTemplateMixin();
@@ -898,7 +898,7 @@ private void emitMemberComments(ScopeDsymbol sds, ref OutBuffer buf, Scope* sc)
     buf.writestring(m);
     size_t offset2 = buf.length; // to see if we write anything
     sc = sc.push(sds);
-    for (size_t i = 0; i < sds.members.dim; i++)
+    for (size_t i = 0; i < sds.members.length; i++)
     {
         Dsymbol s = (*sds.members)[i];
         //printf("\ts = '%s'\n", s.toChars());
@@ -998,7 +998,7 @@ private void emitComment(Dsymbol s, ref OutBuffer buf, Scope* sc)
             // Put previous doc comment if exists
             if (DocComment* dc = sc.lastdc)
             {
-                assert(dc.a.dim > 0, "Expects at least one declaration for a" ~
+                assert(dc.a.length > 0, "Expects at least one declaration for a" ~
                     "documentation comment");
 
                 auto symbol = dc.a[0];
@@ -1010,7 +1010,7 @@ private void emitComment(Dsymbol s, ref OutBuffer buf, Scope* sc)
 
                 // Put the declaration signatures as the document 'title'
                 buf.writestring(ddoc_decl_s);
-                for (size_t i = 0; i < dc.a.dim; i++)
+                for (size_t i = 0; i < dc.a.length; i++)
                 {
                     Dsymbol sx = dc.a[i];
                     // the added linebreaks in here make looking at multiple
@@ -1138,7 +1138,7 @@ private void emitComment(Dsymbol s, ref OutBuffer buf, Scope* sc)
                 return;
             if (ed.isAnonymous() && ed.members)
             {
-                for (size_t i = 0; i < ed.members.dim; i++)
+                for (size_t i = 0; i < ed.members.length; i++)
                 {
                     Dsymbol s = (*ed.members)[i];
                     emitComment(s, *buf, sc);
@@ -1176,7 +1176,7 @@ private void emitComment(Dsymbol s, ref OutBuffer buf, Scope* sc)
             Dsymbols* d = ad.include(null);
             if (d)
             {
-                for (size_t i = 0; i < d.dim; i++)
+                for (size_t i = 0; i < d.length; i++)
                 {
                     Dsymbol s = (*d)[i];
                     //printf("AttribDeclaration::emitComment %s\n", s.toChars());
@@ -1210,7 +1210,7 @@ private void emitComment(Dsymbol s, ref OutBuffer buf, Scope* sc)
              * a template, then include(null) will fail.
              */
             Dsymbols* d = cd.decl ? cd.decl : cd.elsedecl;
-            for (size_t i = 0; i < d.dim; i++)
+            for (size_t i = 0; i < d.length; i++)
             {
                 Dsymbol s = (*d)[i];
                 emitComment(s, *buf, sc);
@@ -1324,9 +1324,9 @@ private void toDocBuffer(Dsymbol s, ref OutBuffer buf, Scope* sc)
             if (d.isVarDeclaration() && td)
             {
                 buf.writeByte('(');
-                if (td.origParameters && td.origParameters.dim)
+                if (td.origParameters && td.origParameters.length)
                 {
-                    for (size_t i = 0; i < td.origParameters.dim; i++)
+                    for (size_t i = 0; i < td.origParameters.length; i++)
                     {
                         if (i)
                             buf.writestring(", ");
@@ -1484,7 +1484,7 @@ private void toDocBuffer(Dsymbol s, ref OutBuffer buf, Scope* sc)
                 buf.printf("%s %s", cd.kind(), cd.toChars());
             }
             int any = 0;
-            for (size_t i = 0; i < cd.baseclasses.dim; i++)
+            for (size_t i = 0; i < cd.baseclasses.length; i++)
             {
                 BaseClass* bc = (*cd.baseclasses)[i];
                 if (bc.sym && bc.sym.ident == Id.Object)
@@ -1557,7 +1557,7 @@ struct DocComment
         if (!comment)
             return dc;
         dc.parseSections(comment);
-        for (size_t i = 0; i < dc.sections.dim; i++)
+        for (size_t i = 0; i < dc.sections.length; i++)
         {
             Section sec = dc.sections[i];
             if (iequals("copyright", sec.name))
@@ -1873,7 +1873,7 @@ struct DocComment
 
     void writeSections(Scope* sc, Dsymbols* a, OutBuffer* buf)
     {
-        assert(a.dim);
+        assert(a.length);
         //printf("DocComment::writeSections()\n");
         Loc loc = (*a)[0].loc;
         if (Module m = (*a)[0].isModule())
@@ -1884,7 +1884,7 @@ struct DocComment
         size_t offset1 = buf.length;
         buf.writestring("$(DDOC_SECTIONS ");
         size_t offset2 = buf.length;
-        for (size_t i = 0; i < sections.dim; i++)
+        for (size_t i = 0; i < sections.length; i++)
         {
             Section sec = sections[i];
             if (sec.nooutput)
@@ -1902,7 +1902,7 @@ struct DocComment
             else
                 sec.write(loc, &this, sc, a, buf);
         }
-        for (size_t i = 0; i < a.dim; i++)
+        for (size_t i = 0; i < a.length; i++)
         {
             Dsymbol s = (*a)[i];
             if (Dsymbol td = getEponymousParent(s))
@@ -2719,7 +2719,7 @@ private Parameter isEponymousFunctionParameter(Dsymbols *a, const(char)[] p) @sa
  */
 private TemplateParameter isTemplateParameter(Dsymbols* a, const(char)* p, size_t len)
 {
-    for (size_t i = 0; i < a.dim; i++)
+    for (size_t i = 0; i < a.length; i++)
     {
         TemplateDeclaration td = (*a)[i].isTemplateDeclaration();
         // Check for the parent, if the current symbol is not a template declaration.
@@ -5004,10 +5004,10 @@ private void highlightText(Scope* sc, Dsymbols* a, Loc loc, ref OutBuffer buf, s
 private void highlightCode(Scope* sc, Dsymbol s, ref OutBuffer buf, size_t offset)
 {
     auto imp = s.isImport();
-    if (imp && imp.aliases.dim > 0)
+    if (imp && imp.aliases.length > 0)
     {
         // For example: `public import core.stdc.string : memcpy, memcmp;`
-        for(int i = 0; i < imp.aliases.dim; i++)
+        for(int i = 0; i < imp.aliases.length; i++)
         {
             // Need to distinguish between
             // `public import core.stdc.string : memcpy, memcmp;` and
@@ -5089,7 +5089,7 @@ private void highlightCode(Scope* sc, Dsymbols* a, ref OutBuffer buf, size_t off
             size_t previ = i;
 
             // hunt for template declarations:
-            foreach (symi; 0 .. a.dim)
+            foreach (symi; 0 .. a.length)
             {
                 FuncDeclaration fd = (*a)[symi].isFuncDeclaration();
 
@@ -5102,14 +5102,14 @@ private void highlightCode(Scope* sc, Dsymbols* a, ref OutBuffer buf, size_t off
 
                 // build the template parameters
                 Array!(size_t) paramLens;
-                paramLens.reserve(td.parameters.dim);
+                paramLens.reserve(td.parameters.length);
 
                 OutBuffer parametersBuf;
                 HdrGenState hgs;
 
                 parametersBuf.writeByte('(');
 
-                foreach (parami; 0 .. td.parameters.dim)
+                foreach (parami; 0 .. td.parameters.length)
                 {
                     TemplateParameter tp = (*td.parameters)[parami];
 
diff --git a/gcc/d/dmd/dscope.d b/gcc/d/dmd/dscope.d
index c8167595708..362e7f27993 100644
--- a/gcc/d/dmd/dscope.d
+++ b/gcc/d/dmd/dscope.d
@@ -71,13 +71,14 @@ private enum PersistentFlags =
     SCOPE.noaccesscheck | SCOPE.ignoresymbolvisibility |
     SCOPE.Cfile;
 
-struct Scope
+extern (C++) struct Scope
 {
     Scope* enclosing;               /// enclosing Scope
 
     Module _module;                 /// Root module
     ScopeDsymbol scopesym;          /// current symbol
     FuncDeclaration func;           /// function we are in
+    VarDeclaration varDecl;         /// variable we are in during semantic2
     Dsymbol parent;                 /// parent to use
     LabelStatement slabel;          /// enclosing labelled statement
     SwitchStatement sw;             /// enclosing switch statement
@@ -177,7 +178,7 @@ struct Scope
         return sc;
     }
 
-    extern (C++) Scope* copy()
+    extern (D) Scope* copy()
     {
         Scope* sc = Scope.alloc();
         *sc = this;
@@ -188,7 +189,7 @@ struct Scope
         return sc;
     }
 
-    extern (C++) Scope* push()
+    extern (D) Scope* push()
     {
         Scope* s = copy();
         //printf("Scope::push(this = %p) new = %p\n", this, s);
@@ -214,7 +215,7 @@ struct Scope
         return s;
     }
 
-    extern (C++) Scope* push(ScopeDsymbol ss)
+    extern (D) Scope* push(ScopeDsymbol ss)
     {
         //printf("Scope::push(%s)\n", ss.toChars());
         Scope* s = push();
@@ -222,7 +223,7 @@ struct Scope
         return s;
     }
 
-    extern (C++) Scope* pop()
+    extern (D) Scope* pop()
     {
         //printf("Scope::pop() %p nofree = %d\n", this, nofree);
         if (enclosing)
@@ -252,7 +253,7 @@ struct Scope
         pop();
     }
 
-    extern (C++) Scope* startCTFE()
+    extern (D) Scope* startCTFE()
     {
         Scope* sc = this.push();
         sc.flags = this.flags | SCOPE.ctfe;
@@ -279,7 +280,7 @@ struct Scope
         return sc;
     }
 
-    extern (C++) Scope* endCTFE()
+    extern (D) Scope* endCTFE()
     {
         assert(flags & SCOPE.ctfe);
         return pop();
@@ -663,7 +664,7 @@ struct Scope
     /********************************************
      * Search enclosing scopes for ScopeDsymbol.
      */
-    ScopeDsymbol getScopesym()
+    extern (D) ScopeDsymbol getScopesym()
     {
         for (Scope* sc = &this; sc; sc = sc.enclosing)
         {
@@ -676,7 +677,7 @@ struct Scope
     /********************************************
      * Search enclosing scopes for ClassDeclaration.
      */
-    extern (C++) ClassDeclaration getClassScope()
+    extern (D) ClassDeclaration getClassScope()
     {
         for (Scope* sc = &this; sc; sc = sc.enclosing)
         {
@@ -691,7 +692,7 @@ struct Scope
     /********************************************
      * Search enclosing scopes for ClassDeclaration or StructDeclaration.
      */
-    extern (C++) AggregateDeclaration getStructClassScope()
+    extern (D) AggregateDeclaration getStructClassScope()
     {
         for (Scope* sc = &this; sc; sc = sc.enclosing)
         {
@@ -713,7 +714,7 @@ struct Scope
      *
      * Returns: the function or null
      */
-    inout(FuncDeclaration) getEnclosingFunction() inout
+    extern (D) inout(FuncDeclaration) getEnclosingFunction() inout
     {
         if (!this.func)
             return null;
@@ -752,7 +753,7 @@ struct Scope
     }
     /******************************
      */
-    structalign_t alignment()
+    extern (D) structalign_t alignment()
     {
         if (aligndecl)
         {
@@ -772,7 +773,7 @@ struct Scope
     *
     * Returns: `true` if this or any parent scope is deprecated, `false` otherwise`
     */
-    extern(C++) bool isDeprecated()
+    extern (D) bool isDeprecated()
     {
         for (const(Dsymbol)* sp = &(this.parent); *sp; sp = &(sp.parent))
         {
@@ -802,7 +803,7 @@ struct Scope
      *
      * Returns: `true` if this `Scope` is known to be from one of these speculative contexts
      */
-    extern(C++) bool isFromSpeculativeSemanticContext() scope
+    extern (D) bool isFromSpeculativeSemanticContext() scope
     {
         return this.intypeof || this.flags & SCOPE.compile;
     }
diff --git a/gcc/d/dmd/dstruct.d b/gcc/d/dmd/dstruct.d
index 1c2f2265328..2115fda2f55 100644
--- a/gcc/d/dmd/dstruct.d
+++ b/gcc/d/dmd/dstruct.d
@@ -292,14 +292,14 @@ extern (C++) class StructDeclaration : AggregateDeclaration
         }
         sizeok = Sizeok.inProcess;
 
-        //printf("+StructDeclaration::finalizeSize() %s, fields.dim = %d, sizeok = %d\n", toChars(), fields.dim, sizeok);
+        //printf("+StructDeclaration::finalizeSize() %s, fields.length = %d, sizeok = %d\n", toChars(), fields.length, sizeok);
 
         fields.setDim(0);   // workaround
 
         // Set the offsets of the fields and determine the size of the struct
         FieldState fieldState;
         bool isunion = isUnionDeclaration() !is null;
-        for (size_t i = 0; i < members.dim; i++)
+        for (size_t i = 0; i < members.length; i++)
         {
             Dsymbol s = (*members)[i];
             s.setFieldOffset(this, fieldState, isunion);
@@ -353,7 +353,7 @@ extern (C++) class StructDeclaration : AggregateDeclaration
 
         sizeok = Sizeok.done;
 
-        //printf("-StructDeclaration::finalizeSize() %s, fields.dim = %d, structsize = %d\n", toChars(), fields.dim, structsize);
+        //printf("-StructDeclaration::finalizeSize() %s, fields.length = %d, structsize = %d\n", toChars(), fields.length, structsize);
 
         if (errors)
             return;
@@ -454,7 +454,7 @@ extern (C++) class StructDeclaration : AggregateDeclaration
         }
 
         // Recursively check all fields are POD.
-        for (size_t i = 0; i < fields.dim; i++)
+        for (size_t i = 0; i < fields.length; i++)
         {
             VarDeclaration v = fields[i];
             if (v.storage_class & STC.ref_)
@@ -491,7 +491,7 @@ extern (C++) class StructDeclaration : AggregateDeclaration
 
     final uint numArgTypes() const
     {
-        return argTypes && argTypes.arguments ? cast(uint) argTypes.arguments.dim : 0;
+        return argTypes && argTypes.arguments ? cast(uint) argTypes.arguments.length : 0;
     }
 
     final Type argType(uint index)
@@ -570,7 +570,7 @@ private bool _isZeroInit(Expression exp)
         case EXP.structLiteral:
         {
             auto sle = cast(StructLiteralExp) exp;
-            foreach (i; 0 .. sle.sd.fields.dim)
+            foreach (i; 0 .. sle.sd.fields.length)
             {
                 auto field = sle.sd.fields[i];
                 if (field.type.size(field.loc))
@@ -588,7 +588,7 @@ private bool _isZeroInit(Expression exp)
         {
             auto ale = cast(ArrayLiteralExp)exp;
 
-            const dim = ale.elements ? ale.elements.dim : 0;
+            const dim = ale.elements ? ale.elements.length : 0;
 
             if (ale.type.toBasetype().ty == Tarray) // if initializing a dynamic array
                 return dim == 0;
diff --git a/gcc/d/dmd/dsymbol.d b/gcc/d/dmd/dsymbol.d
index 2f10e834d9d..2cf5500bf5a 100644
--- a/gcc/d/dmd/dsymbol.d
+++ b/gcc/d/dmd/dsymbol.d
@@ -73,7 +73,7 @@ int foreachDsymbol(Dsymbols* symbols, scope int delegate(Dsymbol) dg)
     {
         /* Do not use foreach, as the size of the array may expand during iteration
          */
-        for (size_t i = 0; i < symbols.dim; ++i)
+        for (size_t i = 0; i < symbols.length; ++i)
         {
             Dsymbol s = (*symbols)[i];
             const result = dg(s);
@@ -99,7 +99,7 @@ void foreachDsymbol(Dsymbols* symbols, scope void delegate(Dsymbol) dg)
     {
         /* Do not use foreach, as the size of the array may expand during iteration
          */
-        for (size_t i = 0; i < symbols.dim; ++i)
+        for (size_t i = 0; i < symbols.length; ++i)
         {
             Dsymbol s = (*symbols)[i];
             dg(s);
@@ -739,7 +739,7 @@ extern (C++) class Dsymbol : ASTNode
         if (a)
         {
             b = a.copy();
-            for (size_t i = 0; i < b.dim; i++)
+            for (size_t i = 0; i < b.length; i++)
             {
                 (*b)[i] = (*b)[i].syntaxCopy(null);
             }
@@ -1164,7 +1164,7 @@ extern (C++) class Dsymbol : ASTNode
      */
     extern (D) static bool oneMembers(Dsymbols* members, Dsymbol* ps, Identifier ident)
     {
-        //printf("Dsymbol::oneMembers() %d\n", members ? members.dim : 0);
+        //printf("Dsymbol::oneMembers() %d\n", members ? members.length : 0);
         Dsymbol s = null;
         if (!members)
         {
@@ -1172,7 +1172,7 @@ extern (C++) class Dsymbol : ASTNode
             return true;
         }
 
-        for (size_t i = 0; i < members.dim; i++)
+        for (size_t i = 0; i < members.length; i++)
         {
             Dsymbol sx = (*members)[i];
             bool x = sx.oneMember(ps, ident);
@@ -1489,7 +1489,7 @@ public:
         Dsymbol s = null;
         OverloadSet a = null;
         // Look in imported modules
-        for (size_t i = 0; i < importedScopes.dim; i++)
+        for (size_t i = 0; i < importedScopes.length; i++)
         {
             // If private import, don't search it
             if ((flags & IgnorePrivateImports) && visibilities[i] == Visibility.Kind.private_)
@@ -1628,14 +1628,14 @@ public:
         if (OverloadSet os2 = s.isOverloadSet())
         {
             // Merge the cross-module overload set 'os2' into 'os'
-            if (os.a.dim == 0)
+            if (os.a.length == 0)
             {
-                os.a.setDim(os2.a.dim);
-                memcpy(os.a.tdata(), os2.a.tdata(), (os.a[0]).sizeof * os2.a.dim);
+                os.a.setDim(os2.a.length);
+                memcpy(os.a.tdata(), os2.a.tdata(), (os.a[0]).sizeof * os2.a.length);
             }
             else
             {
-                for (size_t i = 0; i < os2.a.dim; i++)
+                for (size_t i = 0; i < os2.a.length; i++)
                 {
                     os = mergeOverloadSet(ident, os, os2.a[i]);
                 }
@@ -1646,7 +1646,7 @@ public:
             assert(s.isOverloadable());
             /* Don't add to os[] if s is alias of previous sym
              */
-            for (size_t j = 0; j < os.a.dim; j++)
+            for (size_t j = 0; j < os.a.length; j++)
             {
                 Dsymbol s2 = os.a[j];
                 if (s.toAlias() == s2.toAlias())
@@ -1674,7 +1674,7 @@ public:
                 importedScopes = new Dsymbols();
             else
             {
-                for (size_t i = 0; i < importedScopes.dim; i++)
+                for (size_t i = 0; i < importedScopes.length; i++)
                 {
                     Dsymbol ss = (*importedScopes)[i];
                     if (ss == s) // if already imported
@@ -1686,8 +1686,8 @@ public:
                 }
             }
             importedScopes.push(s);
-            visibilities = cast(Visibility.Kind*)mem.xrealloc(visibilities, importedScopes.dim * (visibilities[0]).sizeof);
-            visibilities[importedScopes.dim - 1] = visibility.kind;
+            visibilities = cast(Visibility.Kind*)mem.xrealloc(visibilities, importedScopes.length * (visibilities[0]).sizeof);
+            visibilities[importedScopes.length - 1] = visibility.kind;
         }
     }
 
@@ -1714,7 +1714,7 @@ public:
         if (!importedScopes)
             return null;
 
-        return (() @trusted => visibilities[0 .. importedScopes.dim])();
+        return (() @trusted => visibilities[0 .. importedScopes.length])();
     }
 
     extern (D) final void addAccessiblePackage(Package p, Visibility visibility) nothrow
@@ -1755,9 +1755,9 @@ public:
         }
         if (loc.isValid())
         {
-            .error(loc, "%s `%s` at %s conflicts with %s `%s` at %s",
-                s1.kind(), s1.toPrettyChars(), s1.locToChars(),
-                s2.kind(), s2.toPrettyChars(), s2.locToChars());
+            .error(loc, "`%s` matches conflicting symbols:", s1.ident.toChars());
+            errorSupplemental(s1.loc, "%s `%s`", s1.kind(), s1.toPrettyChars());
+            errorSupplemental(s2.loc, "%s `%s`", s2.kind(), s2.toPrettyChars());
 
             static if (0)
             {
@@ -1854,7 +1854,7 @@ public:
     {
         if (members)
         {
-            for (size_t i = 0; i < members.dim; i++)
+            for (size_t i = 0; i < members.length; i++)
             {
                 Dsymbol member = (*members)[i];
                 if (member.hasStaticCtorOrDtor())
@@ -1883,7 +1883,7 @@ public:
             return 0;
         size_t n = pn ? *pn : 0; // take over index
         int result = 0;
-        foreach (size_t i; 0 .. members.dim)
+        foreach (size_t i; 0 .. members.length)
         {
             Dsymbol s = (*members)[i];
             if (AttribDeclaration a = s.isAttribDeclaration())
@@ -2020,7 +2020,7 @@ extern (C++) final class ArrayScopeSymbol : ScopeDsymbol
             /* $ gives the number of type entries in the type tuple
              */
             auto v = new VarDeclaration(loc, Type.tsize_t, Id.dollar, null);
-            Expression e = new IntegerExp(Loc.initial, tt.arguments.dim, Type.tsize_t);
+            Expression e = new IntegerExp(Loc.initial, tt.arguments.length, Type.tsize_t);
             v._init = new ExpInitializer(Loc.initial, e);
             v.storage_class |= STC.temp | STC.static_ | STC.const_;
             v.dsymbolSemantic(sc);
@@ -2035,7 +2035,7 @@ extern (C++) final class ArrayScopeSymbol : ScopeDsymbol
             /* $ gives the number of elements in the tuple
              */
             auto v = new VarDeclaration(loc, Type.tsize_t, Id.dollar, null);
-            Expression e = new IntegerExp(Loc.initial, td.objects.dim, Type.tsize_t);
+            Expression e = new IntegerExp(Loc.initial, td.objects.length, Type.tsize_t);
             v._init = new ExpInitializer(Loc.initial, e);
             v.storage_class |= STC.temp | STC.static_ | STC.const_;
             v.dsymbolSemantic(sc);
@@ -2098,7 +2098,7 @@ extern (C++) final class ArrayScopeSymbol : ScopeDsymbol
                 /* It is for an expression tuple, so the
                  * length will be a const.
                  */
-                Expression e = new IntegerExp(Loc.initial, tupexp.exps.dim, Type.tsize_t);
+                Expression e = new IntegerExp(Loc.initial, tupexp.exps.length, Type.tsize_t);
                 v = new VarDeclaration(loc, Type.tsize_t, Id.dollar, new ExpInitializer(Loc.initial, e));
                 v.storage_class |= STC.temp | STC.static_ | STC.const_;
             }
@@ -2142,7 +2142,7 @@ extern (C++) final class ArrayScopeSymbol : ScopeDsymbol
                      * Note that it's impossible to have both template & function opDollar,
                      * because both take no arguments.
                      */
-                    if (exp.op == EXP.array && (cast(ArrayExp)exp).arguments.dim != 1)
+                    if (exp.op == EXP.array && (cast(ArrayExp)exp).arguments.length != 1)
                     {
                         exp.error("`%s` only defines opDollar for one dimension", ad.toChars());
                         return null;
diff --git a/gcc/d/dmd/dsymbolsem.d b/gcc/d/dmd/dsymbolsem.d
index b877828ffe5..b842dc850d1 100644
--- a/gcc/d/dmd/dsymbolsem.d
+++ b/gcc/d/dmd/dsymbolsem.d
@@ -559,19 +559,19 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
                 auto iexps = new Expressions();
                 iexps.push(ie);
                 auto exps = new Expressions();
-                for (size_t pos = 0; pos < iexps.dim; pos++)
+                for (size_t pos = 0; pos < iexps.length; pos++)
                 {
                 Lexpand1:
                     Expression e = (*iexps)[pos];
                     Parameter arg = Parameter.getNth(tt.arguments, pos);
                     arg.type = arg.type.typeSemantic(dsym.loc, sc);
-                    //printf("[%d] iexps.dim = %d, ", pos, iexps.dim);
+                    //printf("[%d] iexps.length = %d, ", pos, iexps.length);
                     //printf("e = (%s %s, %s), ", Token.tochars[e.op], e.toChars(), e.type.toChars());
                     //printf("arg = (%s, %s)\n", arg.toChars(), arg.type.toChars());
 
                     if (e != ie)
                     {
-                        if (iexps.dim > nelems)
+                        if (iexps.length > nelems)
                             goto Lnomatch;
                         if (e.type.implicitConvTo(arg.type))
                             continue;
@@ -579,7 +579,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
 
                     if (auto te = e.isTupleExp())
                     {
-                        if (iexps.dim - 1 + te.exps.dim > nelems)
+                        if (iexps.length - 1 + te.exps.length > nelems)
                             goto Lnomatch;
 
                         iexps.remove(pos);
@@ -598,17 +598,17 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
                         (*exps)[0] = ve;
                         expandAliasThisTuples(exps, 0);
 
-                        for (size_t u = 0; u < exps.dim; u++)
+                        for (size_t u = 0; u < exps.length; u++)
                         {
                         Lexpand2:
                             Expression ee = (*exps)[u];
                             arg = Parameter.getNth(tt.arguments, pos + u);
                             arg.type = arg.type.typeSemantic(dsym.loc, sc);
-                            //printf("[%d+%d] exps.dim = %d, ", pos, u, exps.dim);
+                            //printf("[%d+%d] exps.length = %d, ", pos, u, exps.length);
                             //printf("ee = (%s %s, %s), ", Token.tochars[ee.op], ee.toChars(), ee.type.toChars());
                             //printf("arg = (%s, %s)\n", arg.toChars(), arg.type.toChars());
 
-                            size_t iexps_dim = iexps.dim - 1 + exps.dim;
+                            size_t iexps_dim = iexps.length - 1 + exps.length;
                             if (iexps_dim > nelems)
                                 goto Lnomatch;
                             if (ee.type.implicitConvTo(arg.type))
@@ -630,7 +630,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
                         }
                     }
                 }
-                if (iexps.dim < nelems)
+                if (iexps.length < nelems)
                     goto Lnomatch;
 
                 ie = new TupleExp(dsym._init.loc, iexps);
@@ -640,7 +640,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
             if (ie && ie.op == EXP.tuple)
             {
                 auto te = ie.isTupleExp();
-                size_t tedim = te.exps.dim;
+                size_t tedim = te.exps.length;
                 if (tedim != nelems)
                 {
                     error(dsym.loc, "tuple of %d elements cannot be assigned to tuple of %d elements", cast(int)tedim, cast(int)nelems);
@@ -1065,7 +1065,8 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
                         else if (auto ale = ex.isArrayLiteralExp())
                         {
                             // or an array literal assigned to a `scope` variable
-                            if (!dsym.type.nextOf().needsDestruction())
+                            if (global.params.useDIP1000 == FeatureState.enabled
+                                && !dsym.type.nextOf().needsDestruction())
                                 ale.onstack = true;
                         }
                     }
@@ -1333,7 +1334,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
             if (sc.explicitVisibility)
                 imp.visibility = sc.visibility;
 
-            if (!imp.aliasId && !imp.names.dim) // neither a selective nor a renamed import
+            if (!imp.aliasId && !imp.names.length) // neither a selective nor a renamed import
             {
                 ScopeDsymbol scopesym = sc.getScopesym();
 
@@ -1359,7 +1360,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
 
             sc = sc.push(imp.mod);
             sc.visibility = imp.visibility;
-            for (size_t i = 0; i < imp.aliasdecls.dim; i++)
+            for (size_t i = 0; i < imp.aliasdecls.length; i++)
             {
                 AliasDeclaration ad = imp.aliasdecls[i];
                 //printf("\tImport %s alias %s = %s, scope = %p\n", toPrettyChars(), aliases[i].toChars(), names[i].toChars(), ad._scope);
@@ -1471,7 +1472,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
         {
             Scope* sc2 = ad.newScope(sc);
             bool errors;
-            for (size_t i = 0; i < d.dim; i++)
+            for (size_t i = 0; i < d.length; i++)
             {
                 Dsymbol s = (*d)[i];
                 s.dsymbolSemantic(sc2);
@@ -1509,7 +1510,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
         sc.stc &= ~(STC.auto_ | STC.scope_ | STC.static_ | STC.gshared);
         sc.inunion = scd.isunion ? scd : null;
         sc.flags = 0;
-        for (size_t i = 0; i < scd.decl.dim; i++)
+        for (size_t i = 0; i < scd.decl.length; i++)
         {
             Dsymbol s = (*scd.decl)[i];
             if (auto var = s.isVarDeclaration)
@@ -1627,7 +1628,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
                     if (agg)
                     {
                         ad.pMangleOverride.agg = agg;
-                        if (pd.args.dim == 2)
+                        if (pd.args.length == 2)
                         {
                             setString((*pd.args)[1]);
                         }
@@ -1668,7 +1669,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
         {
             if (pd.ident == Id.linkerDirective)
             {
-                if (!pd.args || pd.args.dim != 1)
+                if (!pd.args || pd.args.length != 1)
                     pd.error("one string argument expected for pragma(linkerDirective)");
                 else
                 {
@@ -1694,7 +1695,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
         }
         else if (pd.ident == Id.lib)
         {
-            if (!pd.args || pd.args.dim != 1)
+            if (!pd.args || pd.args.length != 1)
                 pd.error("string expected for library name");
             else
             {
@@ -1737,9 +1738,9 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
         {
             if (!pd.args)
                 pd.args = new Expressions();
-            if (pd.args.dim == 0 || pd.args.dim > 2)
+            if (pd.args.length == 0 || pd.args.length > 2)
             {
-                pd.error(pd.args.dim == 0 ? "string expected for mangled name"
+                pd.error(pd.args.length == 0 ? "string expected for mangled name"
                                           : "expected 1 or 2 arguments");
                 pd.args.setDim(1);
                 (*pd.args)[0] = ErrorExp.get(); // error recovery
@@ -1748,7 +1749,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
         }
         else if (pd.ident == Id.crt_constructor || pd.ident == Id.crt_destructor)
         {
-            if (pd.args && pd.args.dim != 0)
+            if (pd.args && pd.args.length != 0)
                 pd.error("takes no argument");
             else
             {
@@ -1762,7 +1763,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
                         auto decls = ad.include(null);
                         if (decls)
                         {
-                            for (size_t i = 0; i < decls.dim; ++i)
+                            for (size_t i = 0; i < decls.length; ++i)
                                 nestedCount += recurse((*decls)[i], isCtor);
                         }
                         return nestedCount;
@@ -1788,7 +1789,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
         }
         else if (pd.ident == Id.printf || pd.ident == Id.scanf)
         {
-            if (pd.args && pd.args.dim != 0)
+            if (pd.args && pd.args.length != 0)
                 pd.error("takes no argument");
             return declarations();
         }
@@ -1808,7 +1809,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
         if (pd.args)
         {
             const errors_save = global.startGagging();
-            for (size_t i = 0; i < pd.args.dim; i++)
+            for (size_t i = 0; i < pd.args.length; i++)
             {
                 Expression e = (*pd.args)[i];
                 sc = sc.startCTFE();
@@ -1822,7 +1823,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
                     buf.writeByte(',');
                 buf.writestring(e.toChars());
             }
-            if (pd.args.dim)
+            if (pd.args.length)
                 buf.writeByte(')');
             global.endGagging(errors_save);
         }
@@ -1880,7 +1881,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
 
             if (cd._scope && cd.decl)
             {
-                for (size_t i = 0; i < cd.decl.dim; i++)
+                for (size_t i = 0; i < cd.decl.length; i++)
                 {
                     Dsymbol s = (*cd.decl)[i];
                     s.setScope(cd._scope);
@@ -1919,11 +1920,11 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
         {
             expandTuples(te.exps);
             CPPNamespaceDeclaration current = ns.cppnamespace;
-            for (size_t d = 0; d < te.exps.dim; ++d)
+            for (size_t d = 0; d < te.exps.length; ++d)
             {
                 auto exp = (*te.exps)[d];
                 auto prev = d ? current : ns.cppnamespace;
-                current = (d + 1) != te.exps.dim
+                current = (d + 1) != te.exps.length
                     ? new CPPNamespaceDeclaration(ns.loc, exp, null)
                     : ns;
                 current.exp = exp;
@@ -2122,7 +2123,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
             return;
         }
 
-        if (ed.members.dim == 0)
+        if (ed.members.length == 0)
         {
             ed.error("enum `%s` must have at least one member", ed.toChars());
             ed.errors = true;
@@ -2566,15 +2567,15 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
 
         if (global.params.ddoc.doOutput)
         {
-            tempdecl.origParameters = new TemplateParameters(tempdecl.parameters.dim);
-            for (size_t i = 0; i < tempdecl.parameters.dim; i++)
+            tempdecl.origParameters = new TemplateParameters(tempdecl.parameters.length);
+            for (size_t i = 0; i < tempdecl.parameters.length; i++)
             {
                 TemplateParameter tp = (*tempdecl.parameters)[i];
                 (*tempdecl.origParameters)[i] = tp.syntaxCopy();
             }
         }
 
-        for (size_t i = 0; i < tempdecl.parameters.dim; i++)
+        for (size_t i = 0; i < tempdecl.parameters.length; i++)
         {
             TemplateParameter tp = (*tempdecl.parameters)[i];
             if (!tp.declareParameter(paramscope))
@@ -2586,7 +2587,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
             {
                 tempdecl.errors = true;
             }
-            if (i + 1 != tempdecl.parameters.dim && tp.isTemplateTupleParameter())
+            if (i + 1 != tempdecl.parameters.length && tp.isTemplateTupleParameter())
             {
                 tempdecl.error("template tuple parameter must be last one");
                 tempdecl.errors = true;
@@ -2596,12 +2597,12 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
         /* Calculate TemplateParameter.dependent
          */
         TemplateParameters tparams = TemplateParameters(1);
-        for (size_t i = 0; i < tempdecl.parameters.dim; i++)
+        for (size_t i = 0; i < tempdecl.parameters.length; i++)
         {
             TemplateParameter tp = (*tempdecl.parameters)[i];
             tparams[0] = tp;
 
-            for (size_t j = 0; j < tempdecl.parameters.dim; j++)
+            for (size_t j = 0; j < tempdecl.parameters.length; j++)
             {
                 // Skip cases like: X(T : T)
                 if (i == j)
@@ -2742,10 +2743,10 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
 
             /* Different argument list lengths happen with variadic args
              */
-            if (tm.tiargs.dim != tmix.tiargs.dim)
+            if (tm.tiargs.length != tmix.tiargs.length)
                 continue;
 
-            for (size_t i = 0; i < tm.tiargs.dim; i++)
+            for (size_t i = 0; i < tm.tiargs.length; i++)
             {
                 RootObject o = (*tm.tiargs)[i];
                 Type ta = isType(o);
@@ -2825,7 +2826,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
             printf("\tdo semantic() on template instance members '%s'\n", tm.toChars());
         }
         Scope* sc2 = argscope.push(tm);
-        //size_t deferred_dim = Module.deferred.dim;
+        //size_t deferred_dim = Module.deferred.length;
 
         __gshared int nest;
         //printf("%d\n", nest);
@@ -2848,7 +2849,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
          * Because the members would already call Module.addDeferredSemantic() for themselves.
          * See Struct, Class, Interface, and EnumDeclaration.dsymbolSemantic().
          */
-        //if (!sc.func && Module.deferred.dim > deferred_dim) {}
+        //if (!sc.func && Module.deferred.length > deferred_dim) {}
 
         AggregateDeclaration ad = tm.isMember();
         if (sc.func && !ad)
@@ -3275,6 +3276,8 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
                 funcdecl.error("must return `void` for `pragma(%s)`", idStr.ptr);
             if (funcdecl._linkage != LINK.c && f.parameterList.length != 0)
                 funcdecl.error("must be `extern(C)` for `pragma(%s)` when taking parameters", idStr.ptr);
+            if (funcdecl.isThis())
+                funcdecl.error("cannot be a non-static member function for `pragma(%s)`", idStr.ptr);
         }
 
         if (funcdecl.overnext && funcdecl.isCsymbol())
@@ -3344,7 +3347,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
             {
                 if (!funcdecl.isStatic() || funcdecl.type.nextOf().ty != Tvoid)
                     funcdecl.error("static constructors / destructors must be `static void`");
-                if (f.arguments && f.arguments.dim)
+                if (f.arguments && f.arguments.length)
                     funcdecl.error("static constructors / destructors must have empty parameter list");
                 // BUG: check for invalid storage classes
             }
@@ -3451,13 +3454,13 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
                 goto Ldone;
 
             bool may_override = false;
-            for (size_t i = 0; i < cd.baseclasses.dim; i++)
+            for (size_t i = 0; i < cd.baseclasses.length; i++)
             {
                 BaseClass* b = (*cd.baseclasses)[i];
                 ClassDeclaration cbd = b.type.toBasetype().isClassHandle();
                 if (!cbd)
                     continue;
-                for (size_t j = 0; j < cbd.vtbl.dim; j++)
+                for (size_t j = 0; j < cbd.vtbl.length; j++)
                 {
                     FuncDeclaration f2 = cbd.vtbl[j].isFuncDeclaration();
                     if (!f2 || f2.ident != funcdecl.ident)
@@ -3481,7 +3484,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
             /* Find index of existing function in base class's vtbl[] to override
              * (the index will be the same as in cd's current vtbl[])
              */
-            int vi = cd.baseClass ? funcdecl.findVtblIndex(&cd.baseClass.vtbl, cast(int)cd.baseClass.vtbl.dim) : -1;
+            int vi = cd.baseClass ? funcdecl.findVtblIndex(&cd.baseClass.vtbl, cast(int)cd.baseClass.vtbl.length) : -1;
 
             bool doesoverride = false;
             switch (vi)
@@ -3513,7 +3516,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
                    with offsets to each of the virtual bases.
                  */
                 if (target.cpp.splitVBasetable && cd.classKind == ClassKind.cpp &&
-                    cd.baseClass && cd.baseClass.vtbl.dim)
+                    cd.baseClass && cd.baseClass.vtbl.length)
                 {
                     /* if overriding an interface function, then this is not
                      * introducing and don't put it in the class vtbl[]
@@ -3544,7 +3547,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
                          * Search for first function of overload group, and insert
                          * funcdecl into vtbl[] immediately before it.
                          */
-                        funcdecl.vtblIndex = cast(int)cd.vtbl.dim;
+                        funcdecl.vtblIndex = cast(int)cd.vtbl.length;
                         bool found;
                         foreach (const i, s; cd.vtbl)
                         {
@@ -3574,7 +3577,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
                     else
                     {
                         // Append to end of vtbl[]
-                        vi = cast(int)cd.vtbl.dim;
+                        vi = cast(int)cd.vtbl.length;
                         cd.vtbl.push(funcdecl);
                         funcdecl.vtblIndex = vi;
                     }
@@ -3672,7 +3675,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
                              * will be updated at the end of the enclosing `if` block
                              * to point to the current (non-mixined) function.
                              */
-                            auto vitmp = cast(int)cd.vtbl.dim;
+                            auto vitmp = cast(int)cd.vtbl.length;
                             cd.vtbl.push(fdc);
                             fdc.vtblIndex = vitmp;
                         }
@@ -3683,7 +3686,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
                              * vtbl, but keep the previous (non-mixined) function as
                              * the overriding one.
                              */
-                            auto vitmp = cast(int)cd.vtbl.dim;
+                            auto vitmp = cast(int)cd.vtbl.length;
                             cd.vtbl.push(funcdecl);
                             funcdecl.vtblIndex = vitmp;
                             break;
@@ -3743,7 +3746,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
             {
                 foreach (b; bcd.interfaces)
                 {
-                    vi = funcdecl.findVtblIndex(&b.sym.vtbl, cast(int)b.sym.vtbl.dim);
+                    vi = funcdecl.findVtblIndex(&b.sym.vtbl, cast(int)b.sym.vtbl.length);
                     switch (vi)
                     {
                     case -1:
@@ -3811,7 +3814,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
             {
                 BaseClass* bc = null;
                 Dsymbol s = null;
-                for (size_t i = 0; i < cd.baseclasses.dim; i++)
+                for (size_t i = 0; i < cd.baseclasses.length; i++)
                 {
                     bc = (*cd.baseclasses)[i];
                     s = bc.sym.search_correct(funcdecl.ident);
@@ -4207,7 +4210,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
                     else if (!dd.isFinal())
                     {
                         // reserve the dtor slot for the destructor (which we'll create later)
-                        cldec.cppDtorVtblIndex = cast(int)cldec.vtbl.dim;
+                        cldec.cppDtorVtblIndex = cast(int)cldec.vtbl.length;
                         cldec.vtbl.push(dd);
                         if (target.cpp.twoDtorInVtable)
                             cldec.vtbl.push(dd); // deleting destructor uses a second slot
@@ -4865,7 +4868,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
             cldec.baseok = Baseok.start;
 
             // Expand any tuples in baseclasses[]
-            for (size_t i = 0; i < cldec.baseclasses.dim;)
+            for (size_t i = 0; i < cldec.baseclasses.length;)
             {
                 auto b = (*cldec.baseclasses)[i];
                 b.type = resolveBase(b.type.typeSemantic(cldec.loc, sc));
@@ -4895,7 +4898,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
             }
 
             // See if there's a base class as first in baseclasses[]
-            if (cldec.baseclasses.dim)
+            if (cldec.baseclasses.length)
             {
                 BaseClass* b = (*cldec.baseclasses)[0];
                 Type tb = b.type.toBasetype();
@@ -4955,7 +4958,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
             int multiClassError = cldec.baseClass is null ? 0 : 1;
 
             BCLoop:
-            for (size_t i = (cldec.baseClass ? 1 : 0); i < cldec.baseclasses.dim;)
+            for (size_t i = (cldec.baseClass ? 1 : 0); i < cldec.baseclasses.length;)
             {
                 BaseClass* b = (*cldec.baseclasses)[i];
                 Type tb = b.type.toBasetype();
@@ -4978,7 +4981,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
                                           " Use multiple interface inheritance and/or composition.", cldec.toPrettyChars());
                                 multiClassError += 1;
 
-                                if (tc.sym.fields.dim)
+                                if (tc.sym.fields.length)
                                     errorSupplemental(cldec.loc,"`%s` has fields, consider making it a member of `%s`",
                                                       b.type.toChars(), cldec.type.toChars());
                                 else
@@ -5087,7 +5090,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
                 cldec.storage_class |= cldec.baseClass.storage_class & STC.TYPECTOR;
             }
 
-            cldec.interfaces = cldec.baseclasses.tdata()[(cldec.baseClass ? 1 : 0) .. cldec.baseclasses.dim];
+            cldec.interfaces = cldec.baseclasses.tdata()[(cldec.baseClass ? 1 : 0) .. cldec.baseclasses.length];
             foreach (b; cldec.interfaces)
             {
                 // If this is an interface, and it derives from a COM interface,
@@ -5133,7 +5136,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
             sc2.pop();
         }
 
-        for (size_t i = 0; i < cldec.baseclasses.dim; i++)
+        for (size_t i = 0; i < cldec.baseclasses.length; i++)
         {
             BaseClass* b = (*cldec.baseclasses)[i];
             Type tb = b.type.toBasetype();
@@ -5156,14 +5159,14 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
             // initialize vtbl
             if (cldec.baseClass)
             {
-                if (cldec.classKind == ClassKind.cpp && cldec.baseClass.vtbl.dim == 0)
+                if (cldec.classKind == ClassKind.cpp && cldec.baseClass.vtbl.length == 0)
                 {
                     cldec.error("C++ base class `%s` needs at least one virtual function", cldec.baseClass.toChars());
                 }
 
                 // Copy vtbl[] from base class
-                cldec.vtbl.setDim(cldec.baseClass.vtbl.dim);
-                memcpy(cldec.vtbl.tdata(), cldec.baseClass.vtbl.tdata(), (void*).sizeof * cldec.vtbl.dim);
+                cldec.vtbl.setDim(cldec.baseClass.vtbl.length);
+                memcpy(cldec.vtbl.tdata(), cldec.baseClass.vtbl.tdata(), (void*).sizeof * cldec.vtbl.length);
 
                 cldec.vthis = cldec.baseClass.vthis;
                 cldec.vthis2 = cldec.baseClass.vthis2;
@@ -5237,7 +5240,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
 
         cldec.members.foreachDsymbol( s => s.importAll(sc2) );
 
-        // Note that members.dim can grow due to tuple expansion during semantic()
+        // Note that members.length can grow due to tuple expansion during semantic()
         cldec.members.foreachDsymbol( s => s.dsymbolSemantic(sc2) );
 
         if (!cldec.determineFields())
@@ -5503,7 +5506,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
             idec.baseok = Baseok.start;
 
             // Expand any tuples in baseclasses[]
-            for (size_t i = 0; i < idec.baseclasses.dim;)
+            for (size_t i = 0; i < idec.baseclasses.length;)
             {
                 auto b = (*idec.baseclasses)[i];
                 b.type = resolveBase(b.type.typeSemantic(idec.loc, sc));
@@ -5532,7 +5535,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
                 goto Lancestorsdone;
             }
 
-            if (!idec.baseclasses.dim && sc.linkage == LINK.cpp)
+            if (!idec.baseclasses.length && sc.linkage == LINK.cpp)
                 idec.classKind = ClassKind.cpp;
             idec.cppnamespace = sc.namespace;
             UserAttributeDeclaration.checkGNUABITag(idec, sc.linkage);
@@ -5543,7 +5546,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
 
             // Check for errors, handle forward references
             BCLoop:
-            for (size_t i = 0; i < idec.baseclasses.dim;)
+            for (size_t i = 0; i < idec.baseclasses.length;)
             {
                 BaseClass* b = (*idec.baseclasses)[i];
                 Type tb = b.type.toBasetype();
@@ -5603,7 +5606,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
             }
             idec.baseok = Baseok.done;
 
-            idec.interfaces = idec.baseclasses.tdata()[0 .. idec.baseclasses.dim];
+            idec.interfaces = idec.baseclasses.tdata()[0 .. idec.baseclasses.length];
             foreach (b; idec.interfaces)
             {
                 // If this is an interface, and it derives from a COM interface,
@@ -5626,7 +5629,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
         if (!idec.symtab)
             idec.symtab = new DsymbolTable();
 
-        for (size_t i = 0; i < idec.baseclasses.dim; i++)
+        for (size_t i = 0; i < idec.baseclasses.length; i++)
         {
             BaseClass* b = (*idec.baseclasses)[i];
             Type tb = b.type.toBasetype();
@@ -5662,7 +5665,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
                 // Copy vtbl[] from base class
                 if (b.sym.vtblOffset())
                 {
-                    size_t d = b.sym.vtbl.dim;
+                    size_t d = b.sym.vtbl.length;
                     if (d > 1)
                     {
                         idec.vtbl.pushSlice(b.sym.vtbl[1 .. d]);
@@ -6055,13 +6058,13 @@ void templateInstanceSemantic(TemplateInstance tempinst, Scope* sc, Expressions*
     // Store the place we added it to in target_symbol_list(_idx) so we can
     // remove it later if we encounter an error.
     Dsymbols* target_symbol_list = tempinst.appendToModuleMember();
-    size_t target_symbol_list_idx = target_symbol_list ? target_symbol_list.dim - 1 : 0;
+    size_t target_symbol_list_idx = target_symbol_list ? target_symbol_list.length - 1 : 0;
 
     // Copy the syntax trees from the TemplateDeclaration
     tempinst.members = Dsymbol.arraySyntaxCopy(tempdecl.members);
 
     // resolve TemplateThisParameter
-    for (size_t i = 0; i < tempdecl.parameters.dim; i++)
+    for (size_t i = 0; i < tempdecl.parameters.length; i++)
     {
         if ((*tempdecl.parameters)[i].isTemplateThisParameter() is null)
             continue;
@@ -6126,8 +6129,8 @@ void templateInstanceSemantic(TemplateInstance tempinst, Scope* sc, Expressions*
      * member has the same name as the template instance.
      * If so, this template instance becomes an alias for that member.
      */
-    //printf("members.dim = %d\n", tempinst.members.dim);
-    if (tempinst.members.dim)
+    //printf("members.length = %d\n", tempinst.members.length);
+    if (tempinst.members.length)
     {
         Dsymbol s;
         if (Dsymbol.oneMembers(tempinst.members, &s, tempdecl.ident) && s)
@@ -6172,7 +6175,7 @@ void templateInstanceSemantic(TemplateInstance tempinst, Scope* sc, Expressions*
     /* ConditionalDeclaration may introduce eponymous declaration,
      * so we should find it once again after semantic.
      */
-    if (tempinst.members.dim)
+    if (tempinst.members.length)
     {
         Dsymbol s;
         if (Dsymbol.oneMembers(tempinst.members, &s, tempdecl.ident) && s)
@@ -6195,7 +6198,7 @@ void templateInstanceSemantic(TemplateInstance tempinst, Scope* sc, Expressions*
      */
     {
         bool found_deferred_ad = false;
-        for (size_t i = 0; i < Module.deferred.dim; i++)
+        for (size_t i = 0; i < Module.deferred.length; i++)
         {
             Dsymbol sd = Module.deferred[i];
             AggregateDeclaration ad = sd.isAggregateDeclaration();
@@ -6211,7 +6214,7 @@ void templateInstanceSemantic(TemplateInstance tempinst, Scope* sc, Expressions*
                 }
             }
         }
-        if (found_deferred_ad || Module.deferred.dim)
+        if (found_deferred_ad || Module.deferred.length)
             goto Laftersemantic;
     }
 
@@ -6245,7 +6248,7 @@ void templateInstanceSemantic(TemplateInstance tempinst, Scope* sc, Expressions*
         //printf("Run semantic3 on %s\n", toChars());
         tempinst.trySemantic3(sc2);
 
-        for (size_t i = 0; i < deferred.dim; i++)
+        for (size_t i = 0; i < deferred.length; i++)
         {
             //printf("+ run deferred semantic3 on %s\n", deferred[i].toChars());
             deferred[i].semantic3(null);
@@ -6288,7 +6291,7 @@ void templateInstanceSemantic(TemplateInstance tempinst, Scope* sc, Expressions*
                 {
                     if (!td.literal)
                         continue;
-                    assert(td.members && td.members.dim == 1);
+                    assert(td.members && td.members.length == 1);
                     s = (*td.members)[0];
                 }
                 if (auto fld = s.isFuncLiteralDeclaration())
@@ -6322,7 +6325,7 @@ void templateInstanceSemantic(TemplateInstance tempinst, Scope* sc, Expressions*
             //printf("deferred semantic3 of %p %s, ti = %s, ti.deferred = %p\n", this, toChars(), ti.toChars());
             for (size_t i = 0;; i++)
             {
-                if (i == ti.deferred.dim)
+                if (i == ti.deferred.length)
                 {
                     ti.deferred.push(tempinst);
                     break;
@@ -6553,7 +6556,7 @@ void aliasSemantic(AliasDeclaration ds, Scope* sc)
         // Selective imports are allowed to alias to the same name `import mod : sym=sym`.
         if (!ds._import)
         {
-            if (tident.ident is ds.ident && !tident.idents.dim)
+            if (tident.ident is ds.ident && !tident.idents.length)
             {
                 error(ds.loc, "`alias %s = %s;` cannot alias itself, use a qualified name to create an overload set",
                     ds.ident.toChars(), tident.ident.toChars());
@@ -6958,7 +6961,7 @@ private TupleDeclaration aliasAssignInPlace(Scope* sc, TemplateInstance tempinst
 private TemplateInstance isAliasSeq(Scope* sc, TypeInstance ti)
 {
     auto tovers = ti.tempinst.tempdecl.isOverloadSet();
-    foreach (size_t oi; 0 .. tovers ? tovers.a.dim : 1)
+    foreach (size_t oi; 0 .. tovers ? tovers.a.length : 1)
     {
         Dsymbol dstart = tovers ? tovers.a[oi] : ti.tempinst.tempdecl;
         int r = overloadApply(dstart, (Dsymbol s)
@@ -6994,7 +6997,7 @@ bool determineFields(AggregateDeclaration ad)
     if (ad.sizeok != Sizeok.none)
         return true;
 
-    //printf("determineFields() %s, fields.dim = %d\n", toChars(), fields.dim);
+    //printf("determineFields() %s, fields.length = %d\n", toChars(), fields.length);
     // determineFields can be called recursively from one of the fields's v.semantic
     ad.fields.setDim(0);
 
@@ -7046,7 +7049,7 @@ bool determineFields(AggregateDeclaration ad)
 
     if (ad.members)
     {
-        for (size_t i = 0; i < ad.members.dim; i++)
+        for (size_t i = 0; i < ad.members.length; i++)
         {
             auto s = (*ad.members)[i];
             if (s.apply(&func, ad))
@@ -7123,12 +7126,12 @@ private CallExp doAtomicOp (string op, Identifier var, Expression arg)
  */
 PINLINE evalPragmaInline(Loc loc, Scope* sc, Expressions* args)
 {
-    if (!args || args.dim == 0)
+    if (!args || args.length == 0)
         return PINLINE.default_;
 
-    if (args && args.dim > 1)
+    if (args && args.length > 1)
     {
-        .error(loc, "one boolean expression expected for `pragma(inline)`, not %llu", cast(ulong) args.dim);
+        .error(loc, "one boolean expression expected for `pragma(inline)`, not %llu", cast(ulong) args.length);
         args.setDim(1);
         (*args)[0] = ErrorExp.get();
     }
diff --git a/gcc/d/dmd/dtemplate.d b/gcc/d/dmd/dtemplate.d
index 1f99c58decd..6095dcc9a1e 100644
--- a/gcc/d/dmd/dtemplate.d
+++ b/gcc/d/dmd/dtemplate.d
@@ -362,9 +362,9 @@ private bool arrayObjectMatch(Objects* oa1, Objects* oa2)
 {
     if (oa1 == oa2)
         return true;
-    if (oa1.dim != oa2.dim)
+    if (oa1.length != oa2.length)
         return false;
-    immutable oa1dim = oa1.dim;
+    immutable oa1dim = oa1.length;
     auto oa1d = (*oa1)[].ptr;
     auto oa2d = (*oa2)[].ptr;
     foreach (j; 0 .. oa1dim)
@@ -454,7 +454,7 @@ private size_t expressionHash(Expression e)
     {
         auto ae = e.isArrayLiteralExp();
         size_t hash;
-        foreach (i; 0 .. ae.elements.dim)
+        foreach (i; 0 .. ae.elements.length)
             hash = mixHash(hash, expressionHash(ae[i]));
         return hash;
     }
@@ -463,7 +463,7 @@ private size_t expressionHash(Expression e)
     {
         auto ae = e.isAssocArrayLiteralExp();
         size_t hash;
-        foreach (i; 0 .. ae.keys.dim)
+        foreach (i; 0 .. ae.keys.length)
             // reduction needs associative op as keys are unsorted (use XOR)
             hash ^= mixHash(expressionHash((*ae.keys)[i]), expressionHash((*ae.values)[i]));
         return hash;
@@ -586,7 +586,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
         version (none)
         {
             if (parameters)
-                for (int i = 0; i < parameters.dim; i++)
+                for (int i = 0; i < parameters.length; i++)
                 {
                     TemplateParameter tp = (*parameters)[i];
                     //printf("\tparameter[%d] = %p\n", i, tp);
@@ -660,7 +660,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
         TemplateParameters* p = null;
         if (parameters)
         {
-            p = new TemplateParameters(parameters.dim);
+            p = new TemplateParameters(parameters.length);
             foreach (i, ref param; *p)
                 param = (*parameters)[i].syntaxCopy();
         }
@@ -1059,9 +1059,9 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
         }
         version (none)
         {
-            printf("dedtypes.dim = %d, parameters.dim = %d\n", dedtypes.dim, parameters.dim);
-            if (ti.tiargs.dim)
-                printf("ti.tiargs.dim = %d, [0] = %p\n", ti.tiargs.dim, (*ti.tiargs)[0]);
+            printf("dedtypes.length = %d, parameters.length = %d\n", dedtypes.length, parameters.length);
+            if (ti.tiargs.length)
+                printf("ti.tiargs.length = %d, [0] = %p\n", ti.tiargs.length, (*ti.tiargs)[0]);
         }
         MATCH nomatch()
         {
@@ -1072,18 +1072,18 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
             return MATCH.nomatch;
         }
         MATCH m;
-        size_t dedtypes_dim = dedtypes.dim;
+        size_t dedtypes_dim = dedtypes.length;
 
         dedtypes.zero();
 
         if (errors)
             return MATCH.nomatch;
 
-        size_t parameters_dim = parameters.dim;
+        size_t parameters_dim = parameters.length;
         int variadic = isVariadic() !is null;
 
         // If more arguments than parameters, no match
-        if (ti.tiargs.dim > parameters_dim && !variadic)
+        if (ti.tiargs.length > parameters_dim && !variadic)
         {
             static if (LOGM)
             {
@@ -1093,7 +1093,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
         }
 
         assert(dedtypes_dim == parameters_dim);
-        assert(dedtypes_dim >= ti.tiargs.dim || variadic);
+        assert(dedtypes_dim >= ti.tiargs.length || variadic);
 
         assert(_scope);
 
@@ -1152,7 +1152,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
             {
                 if (!dedtype)
                 {
-                    assert(i < ti.tiargs.dim);
+                    assert(i < ti.tiargs.length);
                     dedtype = cast(Type)(*ti.tiargs)[i];
                 }
             }
@@ -1210,7 +1210,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
                     TemplateParameter tp = (*parameters)[i];
                     RootObject oarg;
                     printf(" [%d]", i);
-                    if (i < ti.tiargs.dim)
+                    if (i < ti.tiargs.length)
                         oarg = (*ti.tiargs)[i];
                     else
                         oarg = null;
@@ -1257,7 +1257,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
         // Set type arguments to dummy template instance to be types
         // generated from the parameters to this template declaration
         auto tiargs = new Objects();
-        tiargs.reserve(parameters.dim);
+        tiargs.reserve(parameters.length);
         foreach (tp; *parameters)
         {
             if (tp.dependent)
@@ -1271,7 +1271,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
         scope TemplateInstance ti = new TemplateInstance(Loc.initial, ident, tiargs); // create dummy template instance
 
         // Temporary Array to hold deduced types
-        Objects dedtypes = Objects(td2.parameters.dim);
+        Objects dedtypes = Objects(td2.parameters.length);
 
         // Attempt a type deduction
         MATCH m = td2.matchWithInstance(sc, ti, &dedtypes, fargs, 1);
@@ -1327,13 +1327,13 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
 
         Loc instLoc = ti.loc;
         Objects* tiargs = ti.tiargs;
-        auto dedargs = new Objects(parameters.dim);
+        auto dedargs = new Objects(parameters.length);
         Objects* dedtypes = &ti.tdtypes; // for T:T*, the dedargs is the T*, dedtypes is the T
 
         version (none)
         {
             printf("\nTemplateDeclaration.deduceFunctionTemplateMatch() %s\n", toChars());
-            for (size_t i = 0; i < (fargs ? fargs.dim : 0); i++)
+            for (size_t i = 0; i < (fargs ? fargs.length : 0); i++)
             {
                 Expression e = (*fargs)[i];
                 printf("\tfarg[%d] is %s, type is %s\n", i, e.toChars(), e.type.toChars());
@@ -1348,7 +1348,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
 
         dedargs.zero();
 
-        dedtypes.setDim(parameters.dim);
+        dedtypes.setDim(parameters.length);
         dedtypes.zero();
 
         if (errors || fd.errors)
@@ -1381,7 +1381,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
 
         version (none)
         {
-            for (size_t i = 0; i < dedargs.dim; i++)
+            for (size_t i = 0; i < dedargs.length; i++)
             {
                 printf("\tdedarg[%d] = ", i);
                 RootObject oarg = (*dedargs)[i];
@@ -1395,8 +1395,8 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
         if (tiargs)
         {
             // Set initial template arguments
-            ntargs = tiargs.dim;
-            size_t n = parameters.dim;
+            ntargs = tiargs.length;
+            size_t n = parameters.length;
             if (tp)
                 n--;
             if (ntargs > n)
@@ -1408,10 +1408,10 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
                  * now form the tuple argument.
                  */
                 auto t = new Tuple(ntargs - n);
-                assert(parameters.dim);
-                (*dedargs)[parameters.dim - 1] = t;
+                assert(parameters.length);
+                (*dedargs)[parameters.length - 1] = t;
 
-                for (size_t i = 0; i < t.objects.dim; i++)
+                for (size_t i = 0; i < t.objects.length; i++)
                 {
                     t.objects[i] = (*tiargs)[n + i];
                 }
@@ -1425,7 +1425,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
 
             for (size_t i = 0; i < n; i++)
             {
-                assert(i < parameters.dim);
+                assert(i < parameters.length);
                 Declaration sparam = null;
                 MATCH m = (*parameters)[i].matchArg(instLoc, paramscope, dedargs, i, parameters, dedtypes, &sparam);
                 //printf("\tdeduceType m = %d\n", m);
@@ -1438,17 +1438,17 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
                 if (!paramscope.insert(sparam))
                     return nomatch();
             }
-            if (n < parameters.dim && !declaredTuple)
+            if (n < parameters.length && !declaredTuple)
             {
                 inferStart = n;
             }
             else
-                inferStart = parameters.dim;
+                inferStart = parameters.length;
             //printf("tiargs matchTiargs = %d\n", matchTiargs);
         }
         version (none)
         {
-            for (size_t i = 0; i < dedargs.dim; i++)
+            for (size_t i = 0; i < dedargs.length; i++)
             {
                 printf("\tdedarg[%d] = ", i);
                 RootObject oarg = (*dedargs)[i];
@@ -1460,7 +1460,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
 
         fparameters = fd.getParameterList();
         nfparams = fparameters.length; // number of function parameters
-        nfargs = fargs ? fargs.dim : 0; // number of function arguments
+        nfargs = fargs ? fargs.length : 0; // number of function arguments
 
         /* Check for match of function arguments with variadic template
          * parameter, such as:
@@ -1479,7 +1479,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
                 {
                     auto t = new Tuple();
                     //printf("t = %p\n", t);
-                    (*dedargs)[parameters.dim - 1] = t;
+                    (*dedargs)[parameters.length - 1] = t;
                     declareParameter(paramscope, tp, t);
                     declaredTuple = t;
                 }
@@ -1497,7 +1497,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
                     if (fparam.type.ty != Tident)
                         continue;
                     TypeIdentifier tid = cast(TypeIdentifier)fparam.type;
-                    if (!tp.ident.equals(tid.ident) || tid.idents.dim)
+                    if (!tp.ident.equals(tid.ident) || tid.idents.length)
                         continue;
 
                     if (fparameters.varargs != VarArg.none) // variadic function doesn't
@@ -1570,7 +1570,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
 
         // Loop through the function parameters
         {
-            //printf("%s\n\tnfargs = %d, nfparams = %d, tuple_dim = %d\n", toChars(), nfargs, nfparams, declaredTuple ? declaredTuple.objects.dim : 0);
+            //printf("%s\n\tnfargs = %d, nfparams = %d, tuple_dim = %d\n", toChars(), nfargs, nfparams, declaredTuple ? declaredTuple.objects.length : 0);
             //printf("\ttp = %p, fptupindex = %d, found = %d, declaredTuple = %s\n", tp, fptupindex, fptupindex != IDX_NOTFOUND, declaredTuple ? declaredTuple.toChars() : NULL);
             size_t argi = 0;
             size_t nfargs2 = nfargs; // nfargs + supplied defaultArgs
@@ -1596,7 +1596,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
                          * now form the tuple argument.
                          */
                         declaredTuple = new Tuple();
-                        (*dedargs)[parameters.dim - 1] = declaredTuple;
+                        (*dedargs)[parameters.length - 1] = declaredTuple;
 
                         /* Count function parameters with no defaults following a tuple parameter.
                          * void foo(U, T...)(int y, T, U, double, int bar = 0) {}  // rem == 2 (U, double)
@@ -1609,10 +1609,10 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
                             {
                                break;
                             }
-                            if (!reliesOnTemplateParameters(p.type, (*parameters)[inferStart .. parameters.dim]))
+                            if (!reliesOnTemplateParameters(p.type, (*parameters)[inferStart .. parameters.length]))
                             {
                                 Type pt = p.type.syntaxCopy().typeSemantic(fd.loc, paramscope);
-                                rem += pt.ty == Ttuple ? (cast(TypeTuple)pt).arguments.dim : 1;
+                                rem += pt.ty == Ttuple ? (cast(TypeTuple)pt).arguments.length : 1;
                             }
                             else
                             {
@@ -1623,7 +1623,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
                         if (nfargs2 - argi < rem)
                             return nomatch();
                         declaredTuple.objects.setDim(nfargs2 - argi - rem);
-                        for (size_t i = 0; i < declaredTuple.objects.dim; i++)
+                        for (size_t i = 0; i < declaredTuple.objects.length; i++)
                         {
                             farg = (*fargs)[argi + i];
 
@@ -1665,20 +1665,20 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
                         // https://issues.dlang.org/show_bug.cgi?id=6810
                         // If declared tuple is not a type tuple,
                         // it cannot be function parameter types.
-                        for (size_t i = 0; i < declaredTuple.objects.dim; i++)
+                        for (size_t i = 0; i < declaredTuple.objects.length; i++)
                         {
                             if (!isType(declaredTuple.objects[i]))
                                 return nomatch();
                         }
                     }
                     assert(declaredTuple);
-                    argi += declaredTuple.objects.dim;
+                    argi += declaredTuple.objects.length;
                     continue;
                 }
 
                 // If parameter type doesn't depend on inferred template parameters,
                 // semantic it to get actual type.
-                if (!reliesOnTemplateParameters(prmtype, (*parameters)[inferStart .. parameters.dim]))
+                if (!reliesOnTemplateParameters(prmtype, (*parameters)[inferStart .. parameters.length]))
                 {
                     // should copy prmtype to avoid affecting semantic result
                     prmtype = prmtype.syntaxCopy().typeSemantic(fd.loc, paramscope);
@@ -1686,7 +1686,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
                     if (prmtype.ty == Ttuple)
                     {
                         TypeTuple tt = cast(TypeTuple)prmtype;
-                        size_t tt_dim = tt.arguments.dim;
+                        size_t tt_dim = tt.arguments.length;
                         for (size_t j = 0; j < tt_dim; j++, ++argi)
                         {
                             Parameter p = (*tt.arguments)[j];
@@ -1748,7 +1748,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
                                 dedtype = xt.tded; // 'unbox'
                             }
                         }
-                        for (size_t i = ntargs; i < dedargs.dim; i++)
+                        for (size_t i = ntargs; i < dedargs.length; i++)
                         {
                             TemplateParameter tparam = (*parameters)[i];
 
@@ -1850,7 +1850,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
                         /* Allow expressions that have CT-known boundaries and type [] to match with [dim]
                          */
                         Type taai;
-                        if (argtype.ty == Tarray && (prmtype.ty == Tsarray || prmtype.ty == Taarray && (taai = (cast(TypeAArray)prmtype).index).ty == Tident && (cast(TypeIdentifier)taai).idents.dim == 0))
+                        if (argtype.ty == Tarray && (prmtype.ty == Tsarray || prmtype.ty == Taarray && (taai = (cast(TypeAArray)prmtype).index).ty == Tident && (cast(TypeIdentifier)taai).idents.length == 0))
                         {
                             if (farg.op == EXP.string_)
                             {
@@ -1860,7 +1860,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
                             else if (farg.op == EXP.arrayLiteral)
                             {
                                 ArrayLiteralExp ae = cast(ArrayLiteralExp)farg;
-                                argtype = ae.type.nextOf().sarrayOf(ae.elements.dim);
+                                argtype = ae.type.nextOf().sarrayOf(ae.elements.length);
                             }
                             else if (farg.op == EXP.slice)
                             {
@@ -1872,7 +1872,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
 
                         oarg = argtype;
                     }
-                    else if ((fparam.storageClass & STC.out_) == 0 && (argtype.ty == Tarray || argtype.ty == Tpointer) && templateParameterLookup(prmtype, parameters) != IDX_NOTFOUND && (cast(TypeIdentifier)prmtype).idents.dim == 0)
+                    else if ((fparam.storageClass & STC.out_) == 0 && (argtype.ty == Tarray || argtype.ty == Tpointer) && templateParameterLookup(prmtype, parameters) != IDX_NOTFOUND && (cast(TypeIdentifier)prmtype).idents.length == 0)
                     {
                         /* The farg passing to the prmtype always make a copy. Therefore,
                          * we can shrink the set of the deduced type arguments for prmtype
@@ -2124,7 +2124,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
                 dedtype = at.merge2();
             }
         }
-        for (size_t i = ntargs; i < dedargs.dim; i++)
+        for (size_t i = ntargs; i < dedargs.length; i++)
         {
             TemplateParameter tparam = (*parameters)[i];
             //printf("tparam[%d] = %s\n", i, tparam.ident.toChars());
@@ -2176,7 +2176,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
                     // we're one or more arguments short (i.e. no tuple argument)
                     if (tparam == tp &&
                         fptupindex == IDX_NOTFOUND &&
-                        ntargs <= dedargs.dim - 1)
+                        ntargs <= dedargs.length - 1)
                     {
                         // make tuple argument an empty tuple
                         oded = new Tuple();
@@ -2215,7 +2215,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
          * As same as the code for 7469 in findBestMatch,
          * expand a Tuple in dedargs to normalize template arguments.
          */
-        if (auto d = dedargs.dim)
+        if (auto d = dedargs.length)
         {
             if (auto va = isTuple((*dedargs)[d - 1]))
             {
@@ -2253,7 +2253,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
 
         version (none)
         {
-            for (size_t i = 0; i < dedargs.dim; i++)
+            for (size_t i = 0; i < dedargs.length; i++)
             {
                 RootObject o = (*dedargs)[i];
                 printf("\tdedargs[%d] = %d, %s\n", i, o.dyncast(), o.toChars());
@@ -2515,7 +2515,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
      */
     TemplateTupleParameter isVariadic()
     {
-        size_t dim = parameters.dim;
+        size_t dim = parameters.length;
         if (dim == 0)
             return null;
         return (*parameters)[dim - 1].isTemplateTupleParameter();
@@ -2612,14 +2612,14 @@ void functionResolve(ref MatchAccumulator m, Dsymbol dstart, Loc loc, Scope* sc,
         printf("    tiargs:\n");
         if (tiargs)
         {
-            for (size_t i = 0; i < tiargs.dim; i++)
+            for (size_t i = 0; i < tiargs.length; i++)
             {
                 RootObject arg = (*tiargs)[i];
                 printf("\t%s\n", arg.toChars());
             }
         }
         printf("    fargs:\n");
-        for (size_t i = 0; i < (fargs ? fargs.dim : 0); i++)
+        for (size_t i = 0; i < (fargs ? fargs.length : 0); i++)
         {
             Expression arg = (*fargs)[i];
             printf("\t%s %s\n", arg.type.toChars(), arg.toChars());
@@ -2645,7 +2645,7 @@ void functionResolve(ref MatchAccumulator m, Dsymbol dstart, Loc loc, Scope* sc,
         if (fd == m.lastf)
             return 0;
         // explicitly specified tiargs never match to non template function
-        if (tiargs && tiargs.dim > 0)
+        if (tiargs && tiargs.length > 0)
             return 0;
 
         // constructors need a valid scope in order to detect semantic errors
@@ -2847,7 +2847,7 @@ void functionResolve(ref MatchAccumulator m, Dsymbol dstart, Loc loc, Scope* sc,
             if (!tiargs)
                 tiargs = new Objects();
             auto ti = new TemplateInstance(loc, td, tiargs);
-            Objects dedtypes = Objects(td.parameters.dim);
+            Objects dedtypes = Objects(td.parameters.length);
             assert(td.semanticRun != PASS.initial);
             MATCH mta = td.matchWithInstance(sc, ti, &dedtypes, fargs, 0);
             //printf("matchWithInstance = %d\n", mta);
@@ -3154,7 +3154,7 @@ void functionResolve(ref MatchAccumulator m, Dsymbol dstart, Loc loc, Scope* sc,
  */
 private size_t templateIdentifierLookup(Identifier id, TemplateParameters* parameters)
 {
-    for (size_t i = 0; i < parameters.dim; i++)
+    for (size_t i = 0; i < parameters.length; i++)
     {
         TemplateParameter tp = (*parameters)[i];
         if (tp.ident.equals(id))
@@ -3536,7 +3536,7 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
                     /* Need a loc to go with the semantic routine.
                      */
                     Loc loc;
-                    if (parameters.dim)
+                    if (parameters.length)
                     {
                         TemplateParameter tp = (*parameters)[0];
                         loc = tp.loc;
@@ -3554,11 +3554,11 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
                 TemplateParameter tp = (*parameters)[i];
 
                 TypeIdentifier tident = cast(TypeIdentifier)tparam;
-                if (tident.idents.dim > 0)
+                if (tident.idents.length > 0)
                 {
                     //printf("matching %s to %s\n", tparam.toChars(), t.toChars());
                     Dsymbol s = t.toDsymbol(sc);
-                    for (size_t j = tident.idents.dim; j-- > 0;)
+                    for (size_t j = tident.idents.length; j-- > 0;)
                     {
                         RootObject id = tident.idents[j];
                         if (id.dyncast() == DYNCAST.identifier)
@@ -3707,7 +3707,7 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
                 /* Need a loc to go with the semantic routine.
                  */
                 Loc loc;
-                if (parameters.dim)
+                if (parameters.length)
                 {
                     TemplateParameter tp = (*parameters)[0];
                     loc = tp.loc;
@@ -3845,7 +3845,7 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
                         // The "type" (it hasn't been resolved yet) of the function parameter
                         // does not have a location but the parameter it is related to does,
                         // so we use that for the resolution (better error message).
-                        if (inferStart < parameters.dim)
+                        if (inferStart < parameters.length)
                         {
                             TemplateParameter loctp = (*parameters)[inferStart];
                             loc = loctp.loc;
@@ -3905,7 +3905,7 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
 
                     // https://issues.dlang.org/show_bug.cgi?id=15243
                     // Resolve parameter type if it's not related with template parameters
-                    if (!reliesOnTemplateParameters(fparam.type, (*parameters)[inferStart .. parameters.dim]))
+                    if (!reliesOnTemplateParameters(fparam.type, (*parameters)[inferStart .. parameters.length]))
                     {
                         auto tx = fparam.type.typeSemantic(Loc.initial, sc);
                         if (tx.ty == Terror)
@@ -3933,7 +3933,7 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
                     if (fparam.type.ty != Tident)
                         goto L1;
                     TypeIdentifier tid = cast(TypeIdentifier)fparam.type;
-                    if (tid.idents.dim)
+                    if (tid.idents.length)
                         goto L1;
 
                     /* Look through parameters to find tuple matching tid.ident
@@ -3941,7 +3941,7 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
                     size_t tupi = 0;
                     for (; 1; tupi++)
                     {
-                        if (tupi == parameters.dim)
+                        if (tupi == parameters.length)
                             goto L1;
                         TemplateParameter tx = (*parameters)[tupi];
                         TemplateTupleParameter tup = tx.isTemplateTupleParameter();
@@ -3961,7 +3961,7 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
                     {
                         // Existing deduced argument must be a tuple, and must match
                         Tuple tup = isTuple(o);
-                        if (!tup || tup.objects.dim != tuple_dim)
+                        if (!tup || tup.objects.length != tuple_dim)
                         {
                             result = MATCH.nomatch;
                             return;
@@ -4023,7 +4023,7 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
             if (tparam && tparam.ty == Tident)
             {
                 TypeIdentifier tp = cast(TypeIdentifier)tparam;
-                for (size_t i = 0; i < t.idents.dim; i++)
+                for (size_t i = 0; i < t.idents.length; i++)
                 {
                     RootObject id1 = t.idents[i];
                     RootObject id2 = tp.idents[i];
@@ -4112,19 +4112,19 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
                 {
                     //printf("\ttest: tempinst.tiargs[%d]\n", i);
                     RootObject o1 = null;
-                    if (i < t.tempinst.tiargs.dim)
+                    if (i < t.tempinst.tiargs.length)
                         o1 = (*t.tempinst.tiargs)[i];
-                    else if (i < t.tempinst.tdtypes.dim && i < tp.tempinst.tiargs.dim)
+                    else if (i < t.tempinst.tdtypes.length && i < tp.tempinst.tiargs.length)
                     {
                         // Pick up default arg
                         o1 = t.tempinst.tdtypes[i];
                     }
-                    else if (i >= tp.tempinst.tiargs.dim)
+                    else if (i >= tp.tempinst.tiargs.length)
                         break;
 
-                    if (i >= tp.tempinst.tiargs.dim)
+                    if (i >= tp.tempinst.tiargs.length)
                     {
-                        size_t dim = tempdecl.parameters.dim - (tempdecl.isVariadic() ? 1 : 0);
+                        size_t dim = tempdecl.parameters.length - (tempdecl.isVariadic() ? 1 : 0);
                         while (i < dim && ((*tempdecl.parameters)[i].dependent || (*tempdecl.parameters)[i].hasDefaultArg()))
                         {
                             i++;
@@ -4137,9 +4137,9 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
                     RootObject o2 = (*tp.tempinst.tiargs)[i];
                     Type t2 = isType(o2);
 
-                    size_t j = (t2 && t2.ty == Tident && i == tp.tempinst.tiargs.dim - 1)
+                    size_t j = (t2 && t2.ty == Tident && i == tp.tempinst.tiargs.length - 1)
                         ? templateParameterLookup(t2, parameters) : IDX_NOTFOUND;
-                    if (j != IDX_NOTFOUND && j == parameters.dim - 1 &&
+                    if (j != IDX_NOTFOUND && j == parameters.length - 1 &&
                         (*parameters)[j].isTemplateTupleParameter())
                     {
                         /* Given:
@@ -4151,12 +4151,12 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
 
                         /* Create tuple from remaining args
                          */
-                        size_t vtdim = (tempdecl.isVariadic() ? t.tempinst.tiargs.dim : t.tempinst.tdtypes.dim) - i;
+                        size_t vtdim = (tempdecl.isVariadic() ? t.tempinst.tiargs.length : t.tempinst.tdtypes.length) - i;
                         auto vt = new Tuple(vtdim);
                         for (size_t k = 0; k < vtdim; k++)
                         {
                             RootObject o;
-                            if (k < t.tempinst.tiargs.dim)
+                            if (k < t.tempinst.tiargs.length)
                                 o = (*t.tempinst.tiargs)[i + k];
                             else // Pick up default arg
                                 o = t.tempinst.tdtypes[i + k];
@@ -4315,9 +4315,9 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
                  *  S!(T).foo
                  */
                 TypeInstance tpi = cast(TypeInstance)tparam;
-                if (tpi.idents.dim)
+                if (tpi.idents.length)
                 {
-                    RootObject id = tpi.idents[tpi.idents.dim - 1];
+                    RootObject id = tpi.idents[tpi.idents.length - 1];
                     if (id.dyncast() == DYNCAST.identifier && t.sym.ident.equals(cast(Identifier)id))
                     {
                         Type tparent = t.sym.parent.getType();
@@ -4325,9 +4325,9 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
                         {
                             /* Slice off the .foo in S!(T).foo
                              */
-                            tpi.idents.dim--;
+                            tpi.idents.length--;
                             result = deduceType(tparent, sc, tpi, parameters, dedtypes, wm);
-                            tpi.idents.dim++;
+                            tpi.idents.length++;
                             return;
                         }
                     }
@@ -4398,8 +4398,8 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
             if (parti)
             {
                 // Make a temporary copy of dedtypes so we don't destroy it
-                auto tmpdedtypes = new Objects(dedtypes.dim);
-                memcpy(tmpdedtypes.tdata(), dedtypes.tdata(), dedtypes.dim * (void*).sizeof);
+                auto tmpdedtypes = new Objects(dedtypes.length);
+                memcpy(tmpdedtypes.tdata(), dedtypes.tdata(), dedtypes.length * (void*).sizeof);
 
                 auto t = new TypeInstance(Loc.initial, parti);
                 MATCH m = deduceType(t, sc, tparam, parameters, tmpdedtypes);
@@ -4407,9 +4407,9 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
                 {
                     // If this is the first ever match, it becomes our best estimate
                     if (numBaseClassMatches == 0)
-                        memcpy(best.tdata(), tmpdedtypes.tdata(), tmpdedtypes.dim * (void*).sizeof);
+                        memcpy(best.tdata(), tmpdedtypes.tdata(), tmpdedtypes.length * (void*).sizeof);
                     else
-                        for (size_t k = 0; k < tmpdedtypes.dim; ++k)
+                        for (size_t k = 0; k < tmpdedtypes.length; ++k)
                         {
                             // If we've found more than one possible type for a parameter,
                             // mark it as unknown.
@@ -4456,9 +4456,9 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
                  *  S!(T).foo
                  */
                 TypeInstance tpi = cast(TypeInstance)tparam;
-                if (tpi.idents.dim)
+                if (tpi.idents.length)
                 {
-                    RootObject id = tpi.idents[tpi.idents.dim - 1];
+                    RootObject id = tpi.idents[tpi.idents.length - 1];
                     if (id.dyncast() == DYNCAST.identifier && t.sym.ident.equals(cast(Identifier)id))
                     {
                         Type tparent = t.sym.parent.getType();
@@ -4466,9 +4466,9 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
                         {
                             /* Slice off the .foo in S!(T).foo
                              */
-                            tpi.idents.dim--;
+                            tpi.idents.length--;
                             result = deduceType(tparent, sc, tpi, parameters, dedtypes, wm);
-                            tpi.idents.dim++;
+                            tpi.idents.length++;
                             return;
                         }
                     }
@@ -4487,10 +4487,10 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
                 int numBaseClassMatches = 0; // Have we found an interface match?
 
                 // Our best guess at dedtypes
-                auto best = new Objects(dedtypes.dim);
+                auto best = new Objects(dedtypes.length);
 
                 ClassDeclaration s = t.sym;
-                while (s && s.baseclasses.dim > 0)
+                while (s && s.baseclasses.length > 0)
                 {
                     // Test the base class
                     deduceBaseClassParameters(*(*s.baseclasses)[0], sc, tparam, parameters, dedtypes, best, numBaseClassMatches);
@@ -4510,7 +4510,7 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
                 }
 
                 // If we got at least one match, copy the known types into dedtypes
-                memcpy(dedtypes.tdata(), best.tdata(), best.dim * (void*).sizeof);
+                memcpy(dedtypes.tdata(), best.tdata(), best.length * (void*).sizeof);
                 result = MATCH.convert;
                 return;
             }
@@ -4536,7 +4536,7 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
         {
             //printf("Expression.deduceType(e = %s)\n", e.toChars());
             size_t i = templateParameterLookup(tparam, parameters);
-            if (i == IDX_NOTFOUND || (cast(TypeIdentifier)tparam).idents.dim > 0)
+            if (i == IDX_NOTFOUND || (cast(TypeIdentifier)tparam).idents.length > 0)
             {
                 if (e == emptyArrayElement && tparam.ty == Tarray)
                 {
@@ -4721,7 +4721,7 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
         override void visit(StringExp e)
         {
             Type taai;
-            if (e.type.ty == Tarray && (tparam.ty == Tsarray || tparam.ty == Taarray && (taai = (cast(TypeAArray)tparam).index).ty == Tident && (cast(TypeIdentifier)taai).idents.dim == 0))
+            if (e.type.ty == Tarray && (tparam.ty == Tsarray || tparam.ty == Taarray && (taai = (cast(TypeAArray)tparam).index).ty == Tident && (cast(TypeIdentifier)taai).idents.length == 0))
             {
                 // Consider compile-time known boundaries
                 e.type.nextOf().sarrayOf(e.len).accept(this);
@@ -4733,19 +4733,19 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
         override void visit(ArrayLiteralExp e)
         {
             // https://issues.dlang.org/show_bug.cgi?id=20092
-            if (e.elements && e.elements.dim && e.type.toBasetype().nextOf().ty == Tvoid)
+            if (e.elements && e.elements.length && e.type.toBasetype().nextOf().ty == Tvoid)
             {
                 result = deduceEmptyArrayElement();
                 return;
             }
-            if ((!e.elements || !e.elements.dim) && e.type.toBasetype().nextOf().ty == Tvoid && tparam.ty == Tarray)
+            if ((!e.elements || !e.elements.length) && e.type.toBasetype().nextOf().ty == Tvoid && tparam.ty == Tarray)
             {
                 // tparam:T[] <- e:[] (void[])
                 result = deduceEmptyArrayElement();
                 return;
             }
 
-            if (tparam.ty == Tarray && e.elements && e.elements.dim)
+            if (tparam.ty == Tarray && e.elements && e.elements.length)
             {
                 Type tn = (cast(TypeDArray)tparam).next;
                 result = MATCH.exact;
@@ -4769,10 +4769,10 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
             }
 
             Type taai;
-            if (e.type.ty == Tarray && (tparam.ty == Tsarray || tparam.ty == Taarray && (taai = (cast(TypeAArray)tparam).index).ty == Tident && (cast(TypeIdentifier)taai).idents.dim == 0))
+            if (e.type.ty == Tarray && (tparam.ty == Tsarray || tparam.ty == Taarray && (taai = (cast(TypeAArray)tparam).index).ty == Tident && (cast(TypeIdentifier)taai).idents.length == 0))
             {
                 // Consider compile-time known boundaries
-                e.type.nextOf().sarrayOf(e.elements.dim).accept(this);
+                e.type.nextOf().sarrayOf(e.elements.length).accept(this);
                 return;
             }
             visit(cast(Expression)e);
@@ -4780,7 +4780,7 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
 
         override void visit(AssocArrayLiteralExp e)
         {
-            if (tparam.ty == Taarray && e.keys && e.keys.dim)
+            if (tparam.ty == Taarray && e.keys && e.keys.length)
             {
                 TypeAArray taa = cast(TypeAArray)tparam;
                 result = MATCH.exact;
@@ -4825,7 +4825,7 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
                     return;
 
                 auto tiargs = new Objects();
-                tiargs.reserve(e.td.parameters.dim);
+                tiargs.reserve(e.td.parameters.length);
 
                 foreach (tp; *e.td.parameters)
                 {
@@ -4841,7 +4841,7 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
                     if (!pto)
                         break;
                     Type t = pto.type.syntaxCopy(); // https://issues.dlang.org/show_bug.cgi?id=11774
-                    if (reliesOnTemplateParameters(t, (*parameters)[inferStart .. parameters.dim]))
+                    if (reliesOnTemplateParameters(t, (*parameters)[inferStart .. parameters.length]))
                         return;
                     t = t.typeSemantic(e.loc, sc);
                     if (t.ty == Terror)
@@ -4885,7 +4885,7 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
         override void visit(SliceExp e)
         {
             Type taai;
-            if (e.type.ty == Tarray && (tparam.ty == Tsarray || tparam.ty == Taarray && (taai = (cast(TypeAArray)tparam).index).ty == Tident && (cast(TypeIdentifier)taai).idents.dim == 0))
+            if (e.type.ty == Tarray && (tparam.ty == Tsarray || tparam.ty == Taarray && (taai = (cast(TypeAArray)tparam).index).ty == Tident && (cast(TypeIdentifier)taai).idents.length == 0))
             {
                 // Consider compile-time known boundaries
                 if (Type tsa = toStaticArrayType(e))
@@ -4928,7 +4928,7 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
  */
 bool reliesOnTident(Type t, TemplateParameters* tparams, size_t iStart = 0)
 {
-    return reliesOnTemplateParameters(t, (*tparams)[0 .. tparams.dim]);
+    return reliesOnTemplateParameters(t, (*tparams)[0 .. tparams.length]);
 }
 
 /***********************************************************
@@ -5739,7 +5739,7 @@ extern (C++) final class TemplateTupleParameter : TemplateParameter
         Tuple v = isTuple(oded);
         assert(v);
 
-        //printf("|%d| ", v.objects.dim);
+        //printf("|%d| ", v.objects.length);
         foreach (i, o; v.objects)
         {
             if (i)
@@ -5901,7 +5901,7 @@ extern (C++) class TemplateInstance : ScopeDsymbol
         Objects* a = null;
         if (objs)
         {
-            a = new Objects(objs.dim);
+            a = new Objects(objs.length);
             foreach (i, o; *objs)
                 (*a)[i] = objectSyntaxCopy(o);
         }
@@ -6094,7 +6094,7 @@ extern (C++) class TemplateInstance : ScopeDsymbol
     final bool equalsx(TemplateInstance ti)
     {
         //printf("this = %p, ti = %p\n", this, ti);
-        assert(tdtypes.dim == ti.tdtypes.dim);
+        assert(tdtypes.length == ti.tdtypes.length);
 
         // Nesting must match
         if (enclosing != ti.enclosing)
@@ -6121,7 +6121,7 @@ extern (C++) class TemplateInstance : ScopeDsymbol
                     Parameter fparam = fparameters[j];
                     if (fparam.storageClass & STC.autoref)       // if "auto ref"
                     {
-                        Expression farg = fargs && j < fargs.dim ? (*fargs)[j] : fparam.defaultArg;
+                        Expression farg = fargs && j < fargs.length ? (*fargs)[j] : fparam.defaultArg;
                         if (!farg)
                             goto Lnotequals;
                         if (farg.isLvalue())
@@ -6423,7 +6423,7 @@ extern (C++) class TemplateInstance : ScopeDsymbol
 
         // Look for forward references
         auto tovers = tempdecl.isOverloadSet();
-        foreach (size_t oi; 0 .. tovers ? tovers.a.dim : 1)
+        foreach (size_t oi; 0 .. tovers ? tovers.a.length : 1)
         {
             Dsymbol dstart = tovers ? tovers.a[oi] : tempdecl;
             int r = overloadApply(dstart, (Dsymbol s)
@@ -6583,7 +6583,7 @@ extern (C++) class TemplateInstance : ScopeDsymbol
         if (!tiargs)
             return true;
         bool err = false;
-        for (size_t j = 0; j < tiargs.dim; j++)
+        for (size_t j = 0; j < tiargs.length; j++)
         {
             RootObject o = (*tiargs)[j];
             Type ta = isType(o);
@@ -6612,7 +6612,7 @@ extern (C++) class TemplateInstance : ScopeDsymbol
                 {
                     // Expand tuple
                     TypeTuple tt = cast(TypeTuple)ta;
-                    size_t dim = tt.arguments.dim;
+                    size_t dim = tt.arguments.length;
                     tiargs.remove(j);
                     if (dim)
                     {
@@ -6688,7 +6688,7 @@ extern (C++) class TemplateInstance : ScopeDsymbol
                 {
                     // Expand tuple
                     TupleExp te = cast(TupleExp)ea;
-                    size_t dim = te.exps.dim;
+                    size_t dim = te.exps.length;
                     tiargs.remove(j);
                     if (dim)
                     {
@@ -6820,7 +6820,7 @@ extern (C++) class TemplateInstance : ScopeDsymbol
         version (none)
         {
             printf("-TemplateInstance.semanticTiargs()\n");
-            for (size_t j = 0; j < tiargs.dim; j++)
+            for (size_t j = 0; j < tiargs.length; j++)
             {
                 RootObject o = (*tiargs)[j];
                 Type ta = isType(o);
@@ -6875,7 +6875,7 @@ extern (C++) class TemplateInstance : ScopeDsymbol
             assert(tempdecl);
             assert(tempdecl._scope);
             // Deduce tdtypes
-            tdtypes.setDim(tempdecl.parameters.dim);
+            tdtypes.setDim(tempdecl.parameters.length);
             if (!tempdecl.matchWithInstance(sc, this, &tdtypes, fargs, 2))
             {
                 error("incompatible arguments for template instantiation");
@@ -6898,7 +6898,7 @@ extern (C++) class TemplateInstance : ScopeDsymbol
          * name, look for the best match.
          */
         auto tovers = tempdecl.isOverloadSet();
-        foreach (size_t oi; 0 .. tovers ? tovers.a.dim : 1)
+        foreach (size_t oi; 0 .. tovers ? tovers.a.length : 1)
         {
             TemplateDeclaration td_best;
             TemplateDeclaration td_ambig;
@@ -6921,13 +6921,13 @@ extern (C++) class TemplateInstance : ScopeDsymbol
                 //printf("td = %s\n", td.toPrettyChars());
                 // If more arguments than parameters,
                 // then this is no match.
-                if (td.parameters.dim < tiargs.dim)
+                if (td.parameters.length < tiargs.length)
                 {
                     if (!td.isVariadic())
                         return 0;
                 }
 
-                dedtypes.setDim(td.parameters.dim);
+                dedtypes.setDim(td.parameters.length);
                 dedtypes.zero();
                 assert(td.semanticRun != PASS.initial);
 
@@ -6960,8 +6960,8 @@ extern (C++) class TemplateInstance : ScopeDsymbol
                 td_ambig = null;
                 td_best = td;
                 m_best = m;
-                tdtypes.setDim(dedtypes.dim);
-                memcpy(tdtypes.tdata(), dedtypes.tdata(), tdtypes.dim * (void*).sizeof);
+                tdtypes.setDim(dedtypes.length);
+                memcpy(tdtypes.tdata(), dedtypes.tdata(), tdtypes.length * (void*).sizeof);
                 return 0;
             });
 
@@ -7000,12 +7000,12 @@ extern (C++) class TemplateInstance : ScopeDsymbol
              *    S!num s;             // S!1 is instantiated, not S!num
              *  }
              */
-            size_t dim = td_last.parameters.dim - (td_last.isVariadic() ? 1 : 0);
+            size_t dim = td_last.parameters.length - (td_last.isVariadic() ? 1 : 0);
             for (size_t i = 0; i < dim; i++)
             {
-                if (tiargs.dim <= i)
+                if (tiargs.length <= i)
                     tiargs.push(tdtypes[i]);
-                assert(i < tiargs.dim);
+                assert(i < tiargs.length);
 
                 auto tvp = (*td_last.parameters)[i].isTemplateValueParameter();
                 if (!tvp)
@@ -7015,7 +7015,7 @@ extern (C++) class TemplateInstance : ScopeDsymbol
 
                 (*tiargs)[i] = tdtypes[i];
             }
-            if (td_last.isVariadic() && tiargs.dim == dim && tdtypes[dim])
+            if (td_last.isVariadic() && tiargs.length == dim && tdtypes[dim])
             {
                 Tuple va = isTuple(tdtypes[dim]);
                 assert(va);
@@ -7051,7 +7051,7 @@ extern (C++) class TemplateInstance : ScopeDsymbol
                 {
                     error("%s `%s`", msg, tmsg);
 
-                    if (tdecl.parameters.dim == tiargs.dim)
+                    if (tdecl.parameters.length == tiargs.length)
                     {
                         // https://issues.dlang.org/show_bug.cgi?id=7352
                         // print additional information, e.g. `foo` is not a type
@@ -7081,7 +7081,17 @@ extern (C++) class TemplateInstance : ScopeDsymbol
                 }
             }
             else
-                .error(loc, "%s `%s.%s` does not match any template declaration", tempdecl.kind(), tempdecl.parent.toPrettyChars(), tempdecl.ident.toChars());
+            {
+                .error(loc, "%s `%s` does not match any template declaration", kind(), toPrettyChars());
+                bool found;
+                overloadApply(tempdecl, (s){
+                    if (!found)
+                        errorSupplemental(loc, "Candidates are:");
+                    found = true;
+                    errorSupplemental(s.loc, "%s", s.toChars());
+                    return 0;
+                });
+            }
             return false;
         }
 
@@ -7115,7 +7125,7 @@ extern (C++) class TemplateInstance : ScopeDsymbol
         size_t count = 0;
 
         auto tovers = tempdecl.isOverloadSet();
-        foreach (size_t oi; 0 .. tovers ? tovers.a.dim : 1)
+        foreach (size_t oi; 0 .. tovers ? tovers.a.length : 1)
         {
             Dsymbol dstart = tovers ? tovers.a[oi] : tempdecl;
             int r = overloadApply(dstart, (Dsymbol s)
@@ -7138,7 +7148,7 @@ extern (C++) class TemplateInstance : ScopeDsymbol
                 {
                     if (!td2.onemember || !td2.onemember.isFuncDeclaration())
                         return 0;
-                    if (tiargs.dim >= td.parameters.dim - (td.isVariadic() ? 1 : 0))
+                    if (tiargs.length >= td.parameters.length - (td.isVariadic() ? 1 : 0))
                         return 0;
                     return 1;
                 }
@@ -7155,18 +7165,18 @@ extern (C++) class TemplateInstance : ScopeDsymbol
                 /* Determine if the instance arguments, tiargs, are all that is necessary
                  * to instantiate the template.
                  */
-                //printf("tp = %p, td.parameters.dim = %d, tiargs.dim = %d\n", tp, td.parameters.dim, tiargs.dim);
+                //printf("tp = %p, td.parameters.length = %d, tiargs.length = %d\n", tp, td.parameters.length, tiargs.length);
                 auto tf = cast(TypeFunction)fd.type;
                 if (tf.parameterList.length)
                 {
                     auto tp = td.isVariadic();
-                    if (tp && td.parameters.dim > 1)
+                    if (tp && td.parameters.length > 1)
                         return 1;
 
-                    if (!tp && tiargs.dim < td.parameters.dim)
+                    if (!tp && tiargs.length < td.parameters.length)
                     {
                         // Can remain tiargs be filled by default arguments?
-                        foreach (size_t i; tiargs.dim .. td.parameters.dim)
+                        foreach (size_t i; tiargs.length .. td.parameters.length)
                         {
                             if (!(*td.parameters)[i].hasDefaultArg())
                                 return 1;
@@ -7186,7 +7196,7 @@ extern (C++) class TemplateInstance : ScopeDsymbol
                     /* Calculate the need for overload resolution.
                      * When only one template can match with tiargs, inference is not necessary.
                      */
-                    dedtypes.setDim(td.parameters.dim);
+                    dedtypes.setDim(td.parameters.length);
                     dedtypes.zero();
                     if (td.semanticRun == PASS.initial)
                     {
@@ -7653,7 +7663,7 @@ extern (C++) final class TemplateMixin : TemplateInstance
     extern (D) this(const ref Loc loc, Identifier ident, TypeQualified tqual, Objects* tiargs)
     {
         super(loc,
-              tqual.idents.dim ? cast(Identifier)tqual.idents[tqual.idents.dim - 1] : (cast(TypeIdentifier)tqual).ident,
+              tqual.idents.length ? cast(Identifier)tqual.idents[tqual.idents.length - 1] : (cast(TypeIdentifier)tqual).ident,
               tiargs ? tiargs : new Objects());
         //printf("TemplateMixin(ident = '%s')\n", ident ? ident.toChars() : "");
         this.ident = ident;
@@ -7745,7 +7755,7 @@ extern (C++) final class TemplateMixin : TemplateInstance
 
         // Look for forward references
         auto tovers = tempdecl.isOverloadSet();
-        foreach (size_t oi; 0 .. tovers ? tovers.a.dim : 1)
+        foreach (size_t oi; 0 .. tovers ? tovers.a.length : 1)
         {
             Dsymbol dstart = tovers ? tovers.a[oi] : tempdecl;
             int r = overloadApply(dstart, (Dsymbol s)
@@ -7865,7 +7875,7 @@ MATCH matchArg(TemplateParameter tp, Loc instLoc, Scope* sc, Objects* tiargs, si
     {
         RootObject oarg;
 
-        if (i < tiargs.dim)
+        if (i < tiargs.length)
             oarg = (*tiargs)[i];
         else
         {
@@ -7873,7 +7883,7 @@ MATCH matchArg(TemplateParameter tp, Loc instLoc, Scope* sc, Objects* tiargs, si
             oarg = tp.defaultArg(instLoc, sc);
             if (!oarg)
             {
-                assert(i < dedtypes.dim);
+                assert(i < dedtypes.length);
                 // It might have already been deduced
                 oarg = (*dedtypes)[i];
                 if (!oarg)
@@ -7888,7 +7898,7 @@ MATCH matchArg(TemplateParameter tp, Loc instLoc, Scope* sc, Objects* tiargs, si
         /* The rest of the actual arguments (tiargs[]) form the match
          * for the variadic parameter.
          */
-        assert(i + 1 == dedtypes.dim); // must be the last one
+        assert(i + 1 == dedtypes.length); // must be the last one
         Tuple ovar;
 
         if (Tuple u = isTuple((*dedtypes)[i]))
@@ -7896,16 +7906,16 @@ MATCH matchArg(TemplateParameter tp, Loc instLoc, Scope* sc, Objects* tiargs, si
             // It has already been deduced
             ovar = u;
         }
-        else if (i + 1 == tiargs.dim && isTuple((*tiargs)[i]))
+        else if (i + 1 == tiargs.length && isTuple((*tiargs)[i]))
             ovar = isTuple((*tiargs)[i]);
         else
         {
             ovar = new Tuple();
             //printf("ovar = %p\n", ovar);
-            if (i < tiargs.dim)
+            if (i < tiargs.length)
             {
-                //printf("i = %d, tiargs.dim = %d\n", i, tiargs.dim);
-                ovar.objects.setDim(tiargs.dim - i);
+                //printf("i = %d, tiargs.length = %d\n", i, tiargs.length);
+                ovar.objects.setDim(tiargs.length - i);
                 foreach (j, ref obj; ovar.objects)
                     obj = (*tiargs)[i + j];
             }
diff --git a/gcc/d/dmd/dtoh.d b/gcc/d/dmd/dtoh.d
index c570068f7d6..432e88da307 100644
--- a/gcc/d/dmd/dtoh.d
+++ b/gcc/d/dmd/dtoh.d
@@ -1945,7 +1945,7 @@ public:
         }
         if (tf.parameterList.varargs)
         {
-            if (tf.parameterList.parameters.dim && tf.parameterList.varargs == 1)
+            if (tf.parameterList.parameters.length && tf.parameterList.varargs == 1)
                 buf.writestring(", ");
             buf.writestring("...");
         }
@@ -2280,7 +2280,7 @@ public:
         }
         if (tf.parameterList.varargs)
         {
-            if (tf.parameterList.parameters.dim && tf.parameterList.varargs == 1)
+            if (tf.parameterList.parameters.length && tf.parameterList.varargs == 1)
                 buf.writestring(", ");
             buf.writestring("...");
         }
diff --git a/gcc/d/dmd/escape.d b/gcc/d/dmd/escape.d
index e7626b0b147..24a428b6ce6 100644
--- a/gcc/d/dmd/escape.d
+++ b/gcc/d/dmd/escape.d
@@ -328,7 +328,7 @@ void printScopeFailure(E)(E printFunc, VarDeclaration v, int recursionLimit)
  * Params:
  *      sc = used to determine current function and module
  *      fdc = function being called, `null` if called indirectly
- *      par = function parameter (`this` if null)
+ *      parId = name of function parameter for error messages
  *      vPar = `VarDeclaration` corresponding to `par`
  *      parStc = storage classes of function parameter (may have added `scope` from `pure`)
  *      arg = initializer for param
@@ -337,12 +337,12 @@ void printScopeFailure(E)(E printFunc, VarDeclaration v, int recursionLimit)
  * Returns:
  *      `true` if pointers to the stack can escape via assignment
  */
-bool checkParamArgumentEscape(Scope* sc, FuncDeclaration fdc, Parameter par, VarDeclaration vPar, STC parStc, Expression arg, bool assertmsg, bool gag)
+bool checkParamArgumentEscape(Scope* sc, FuncDeclaration fdc, Identifier parId, VarDeclaration vPar, STC parStc, Expression arg, bool assertmsg, bool gag)
 {
     enum log = false;
     if (log) printf("checkParamArgumentEscape(arg: %s par: %s)\n",
         arg ? arg.toChars() : "null",
-        par ? par.toChars() : "this");
+        parId ? parId.toChars() : "null");
     //printf("type = %s, %d\n", arg.type.toChars(), arg.type.hasPointers());
 
     if (!arg.type.hasPointers())
@@ -361,7 +361,7 @@ bool checkParamArgumentEscape(Scope* sc, FuncDeclaration fdc, Parameter par, Var
         er.byexp.setDim(0);
     }
 
-    if (!er.byref.dim && !er.byvalue.dim && !er.byfunc.dim && !er.byexp.dim)
+    if (!er.byref.length && !er.byvalue.length && !er.byfunc.length && !er.byexp.length)
         return false;
 
     bool result = false;
@@ -374,24 +374,18 @@ bool checkParamArgumentEscape(Scope* sc, FuncDeclaration fdc, Parameter par, Var
         {
             result |= sc.setUnsafeDIP1000(gag, arg.loc,
                 desc ~ " `%s` assigned to non-scope parameter calling `assert()`", v);
+            return;
         }
-        else if (par)
-        {
-            if (sc.setUnsafeDIP1000(gag, arg.loc,
-                desc ~ " `%s` assigned to non-scope parameter `%s` calling `%s`", v, par, fdc))
-            {
-                result = true;
-                printScopeFailure(previewSupplementalFunc(sc.isDeprecated(), global.params.useDIP1000), vPar, 10);
-            }
-        }
-        else
+        const(char)* msg =
+            (fdc &&  parId) ? (desc ~ " `%s` assigned to non-scope parameter `%s` calling `%s`") :
+            (fdc && !parId) ? (desc ~ " `%s` assigned to non-scope anonymous parameter calling `%s`") :
+            (!fdc && parId) ? (desc ~ " `%s` assigned to non-scope parameter `%s`") :
+            (desc ~ " `%s` assigned to non-scope anonymous parameter");
+
+        if (sc.setUnsafeDIP1000(gag, arg.loc, msg, v, parId ? parId : fdc, fdc))
         {
-            if (sc.setUnsafeDIP1000(gag, arg.loc,
-                desc ~ " `%s` assigned to non-scope parameter `this` calling `%s`", v, fdc))
-            {
-                result = true;
-                printScopeFailure(previewSupplementalFunc(sc.isDeprecated(), global.params.useDIP1000), fdc.vthis, 10);
-            }
+            result = true;
+            printScopeFailure(previewSupplementalFunc(sc.isDeprecated(), global.params.useDIP1000), vPar, 10);
         }
     }
 
@@ -465,16 +459,11 @@ bool checkParamArgumentEscape(Scope* sc, FuncDeclaration fdc, Parameter par, Var
 
     foreach (Expression ee; er.byexp)
     {
-        if (!par)
-        {
-            result |= sc.setUnsafeDIP1000(gag, ee.loc,
-                "reference to stack allocated value returned by `%s` assigned to non-scope parameter `this`", ee);
-        }
-        else
-        {
-            result |= sc.setUnsafeDIP1000(gag, ee.loc,
-                "reference to stack allocated value returned by `%s` assigned to non-scope parameter `%s`", ee, par);
-        }
+        const(char)* msg = parId ?
+            "reference to stack allocated value returned by `%s` assigned to non-scope parameter `%s`" :
+            "reference to stack allocated value returned by `%s` assigned to non-scope anonymous parameter";
+
+        result |= sc.setUnsafeDIP1000(gag, ee.loc, msg, ee, parId);
     }
 
     return result;
@@ -537,7 +526,7 @@ bool checkConstructorEscape(Scope* sc, CallExp ce, bool gag)
     if (!tthis.hasPointers())
         return false;
 
-    if (!ce.arguments && ce.arguments.dim)
+    if (!ce.arguments && ce.arguments.length)
         return false;
 
     DotVarExp dve = ce.e1.isDotVarExp();
@@ -545,7 +534,7 @@ bool checkConstructorEscape(Scope* sc, CallExp ce, bool gag)
     TypeFunction tf = ctor.type.isTypeFunction();
 
     const nparams = tf.parameterList.length;
-    const n = ce.arguments.dim;
+    const n = ce.arguments.length;
 
     // j=1 if _arguments[] is first argument
     const j = tf.isDstyleVariadic();
@@ -625,7 +614,7 @@ bool checkAssignEscape(Scope* sc, Expression e, bool gag, bool byRef)
     else
         escapeByValue(e2, &er);
 
-    if (!er.byref.dim && !er.byvalue.dim && !er.byfunc.dim && !er.byexp.dim)
+    if (!er.byref.length && !er.byvalue.length && !er.byfunc.length && !er.byexp.length)
         return false;
 
     VarDeclaration va = expToVariable(e1);
@@ -959,7 +948,7 @@ bool checkThrowEscape(Scope* sc, Expression e, bool gag)
 
     escapeByValue(e, &er);
 
-    if (!er.byref.dim && !er.byvalue.dim && !er.byexp.dim)
+    if (!er.byref.length && !er.byvalue.length && !er.byexp.length)
         return false;
 
     bool result = false;
@@ -1007,7 +996,7 @@ bool checkNewEscape(Scope* sc, Expression e, bool gag)
 
     escapeByValue(e, &er);
 
-    if (!er.byref.dim && !er.byvalue.dim && !er.byexp.dim)
+    if (!er.byref.length && !er.byvalue.length && !er.byexp.length)
         return false;
 
     bool result = false;
@@ -1187,7 +1176,7 @@ private bool checkReturnEscapeImpl(Scope* sc, Expression e, bool refs, bool gag)
     else
         escapeByValue(e, &er);
 
-    if (!er.byref.dim && !er.byvalue.dim && !er.byexp.dim)
+    if (!er.byref.length && !er.byvalue.length && !er.byexp.length)
         return false;
 
     bool result = false;
@@ -1739,13 +1728,13 @@ void escapeByValue(Expression e, EscapeByResults* er, bool live = false, bool re
         if (!e.type.hasPointers())
             return;
 
-        if (e.arguments && e.arguments.dim)
+        if (e.arguments && e.arguments.length)
         {
             /* j=1 if _arguments[] is first argument,
              * skip it because it is not passed by ref
              */
             int j = tf.isDstyleVariadic();
-            for (size_t i = j; i < e.arguments.dim; ++i)
+            for (size_t i = j; i < e.arguments.length; ++i)
             {
                 Expression arg = (*e.arguments)[i];
                 size_t nparams = tf.parameterList.length;
@@ -2048,13 +2037,13 @@ void escapeByRef(Expression e, EscapeByResults* er, bool live = false, bool retR
             return;
         if (tf.isref)
         {
-            if (e.arguments && e.arguments.dim)
+            if (e.arguments && e.arguments.length)
             {
                 /* j=1 if _arguments[] is first argument,
                  * skip it because it is not passed by ref
                  */
                 int j = tf.isDstyleVariadic();
-                for (size_t i = j; i < e.arguments.dim; ++i)
+                for (size_t i = j; i < e.arguments.length; ++i)
                 {
                     Expression arg = (*e.arguments)[i];
                     size_t nparams = tf.parameterList.length;
@@ -2323,7 +2312,7 @@ void finishScopeParamInference(FuncDeclaration funcdecl, ref TypeFunction f)
     {
         // Create and fill array[] with maybe candidates from the `this` and the parameters
         VarDeclaration[10] tmp = void;
-        size_t dim = (funcdecl.vthis !is null) + (funcdecl.parameters ? funcdecl.parameters.dim : 0);
+        size_t dim = (funcdecl.vthis !is null) + (funcdecl.parameters ? funcdecl.parameters.length : 0);
 
         import dmd.common.string : SmallBuffer;
         auto sb = SmallBuffer!VarDeclaration(dim, tmp[]);
@@ -2345,7 +2334,7 @@ void finishScopeParamInference(FuncDeclaration funcdecl, ref TypeFunction f)
     // Infer STC.scope_
     if (funcdecl.parameters && !funcdecl.errors)
     {
-        assert(f.parameterList.length == funcdecl.parameters.dim);
+        assert(f.parameterList.length == funcdecl.parameters.length);
         foreach (u, p; f.parameterList)
         {
             auto v = (*funcdecl.parameters)[u];
diff --git a/gcc/d/dmd/expression.d b/gcc/d/dmd/expression.d
index 21f5cc76a4b..4f14d66d39f 100644
--- a/gcc/d/dmd/expression.d
+++ b/gcc/d/dmd/expression.d
@@ -260,7 +260,7 @@ extern (C++) void expandTuples(Expressions* exps)
     if (exps is null)
         return;
 
-    for (size_t i = 0; i < exps.dim; i++)
+    for (size_t i = 0; i < exps.length; i++)
     {
         Expression arg = (*exps)[i];
         if (!arg)
@@ -271,10 +271,10 @@ extern (C++) void expandTuples(Expressions* exps)
         {
             if (auto tt = e.type.toBasetype().isTypeTuple())
             {
-                if (!tt.arguments || tt.arguments.dim == 0)
+                if (!tt.arguments || tt.arguments.length == 0)
                 {
                     exps.remove(i);
-                    if (i == exps.dim)
+                    if (i == exps.length)
                         return;
                 }
                 else // Expand a TypeTuple
@@ -296,7 +296,7 @@ extern (C++) void expandTuples(Expressions* exps)
             TupleExp te = cast(TupleExp)arg;
             exps.remove(i); // remove arg
             exps.insert(i, te.exps); // replace with tuple contents
-            if (i == exps.dim)
+            if (i == exps.length)
                 return; // empty tuple, no more arguments
             (*exps)[i] = Expression.combine(te.e0, (*exps)[i]);
             arg = (*exps)[i];
@@ -339,10 +339,10 @@ TupleDeclaration isAliasThisTuple(Expression e)
 
 int expandAliasThisTuples(Expressions* exps, size_t starti = 0)
 {
-    if (!exps || exps.dim == 0)
+    if (!exps || exps.length == 0)
         return -1;
 
-    for (size_t u = starti; u < exps.dim; u++)
+    for (size_t u = starti; u < exps.length; u++)
     {
         Expression exp = (*exps)[u];
         if (TupleDeclaration td = exp.isAliasThisTuple)
@@ -924,7 +924,7 @@ extern (C++) abstract class Expression : ASTNode
         Expressions* a = null;
         if (exps)
         {
-            a = new Expressions(exps.dim);
+            a = new Expressions(exps.length);
             foreach (i, e; *exps)
             {
                 (*a)[i] = e ? e.syntaxCopy() : null;
@@ -1214,7 +1214,7 @@ extern (C++) abstract class Expression : ASTNode
         auto ad = cast(AggregateDeclaration) f.toParent2();
         assert(ad);
 
-        if (ad.userDtors.dim)
+        if (ad.userDtors.length)
         {
             if (!check(ad.userDtors[0])) // doesn't match check (e.g. is impure as well)
                 return;
@@ -1401,14 +1401,32 @@ extern (C++) abstract class Expression : ASTNode
      */
     extern (D) final bool checkSafety(Scope* sc, FuncDeclaration f)
     {
-        if (!sc.func)
-            return false;
         if (sc.func == f)
             return false;
         if (sc.intypeof == 1)
             return false;
-        if (sc.flags & (SCOPE.ctfe | SCOPE.debug_))
+        if (sc.flags & SCOPE.debug_)
             return false;
+        if ((sc.flags & SCOPE.ctfe) && sc.func)
+            return false;
+
+        if (!sc.func)
+        {
+            if (sc.varDecl && !f.safetyInprocess && !f.isSafe() && !f.isTrusted())
+            {
+                if (sc.varDecl.storage_class & STC.safe)
+                {
+                    error("`@safe` variable `%s` cannot be initialized by calling `@system` function `%s`",
+                        sc.varDecl.toChars(), f.toChars());
+                    return true;
+                }
+                else
+                {
+                    sc.varDecl.storage_class |= STC.system;
+                }
+            }
+            return false;
+        }
 
         if (!f.isSafe() && !f.isTrusted())
         {
@@ -2867,7 +2885,7 @@ extern (C++) final class TupleExp : Expression
         super(loc, EXP.tuple, __traits(classInstanceSize, TupleExp));
         this.exps = new Expressions();
 
-        this.exps.reserve(tup.objects.dim);
+        this.exps.reserve(tup.objects.length);
         foreach (o; *tup.objects)
         {
             if (Dsymbol s = getDsymbol(o))
@@ -2913,7 +2931,7 @@ extern (C++) final class TupleExp : Expression
         if (auto e = o.isExpression())
             if (auto te = e.isTupleExp())
             {
-                if (exps.dim != te.exps.dim)
+                if (exps.length != te.exps.length)
                     return false;
                 if (e0 && !e0.equals(te.e0) || !e0 && te.e0)
                     return false;
@@ -3002,9 +3020,9 @@ extern (C++) final class ArrayLiteralExp : Expression
             return false;
         if (auto ae = e.isArrayLiteralExp())
         {
-            if (elements.dim != ae.elements.dim)
+            if (elements.length != ae.elements.length)
                 return false;
-            if (elements.dim == 0 && !type.equals(ae.type))
+            if (elements.length == 0 && !type.equals(ae.type))
             {
                 return false;
             }
@@ -3036,14 +3054,14 @@ extern (C++) final class ArrayLiteralExp : Expression
 
     override Optional!bool toBool()
     {
-        size_t dim = elements ? elements.dim : 0;
+        size_t dim = elements ? elements.length : 0;
         return typeof(return)(dim != 0);
     }
 
     override StringExp toStringExp()
     {
         TY telem = type.nextOf().toBasetype().ty;
-        if (telem.isSomeChar || (telem == Tvoid && (!elements || elements.dim == 0)))
+        if (telem.isSomeChar || (telem == Tvoid && (!elements || elements.length == 0)))
         {
             ubyte sz = 1;
             if (telem == Twchar)
@@ -3054,7 +3072,7 @@ extern (C++) final class ArrayLiteralExp : Expression
             OutBuffer buf;
             if (elements)
             {
-                foreach (i; 0 .. elements.dim)
+                foreach (i; 0 .. elements.length)
                 {
                     auto ch = this[i];
                     if (ch.op != EXP.int64)
@@ -3114,7 +3132,7 @@ extern (C++) final class AssocArrayLiteralExp : Expression
     extern (D) this(const ref Loc loc, Expressions* keys, Expressions* values)
     {
         super(loc, EXP.assocArrayLiteral, __traits(classInstanceSize, AssocArrayLiteralExp));
-        assert(keys.dim == values.dim);
+        assert(keys.length == values.length);
         this.keys = keys;
         this.values = values;
     }
@@ -3128,7 +3146,7 @@ extern (C++) final class AssocArrayLiteralExp : Expression
             return false;
         if (auto ae = e.isAssocArrayLiteralExp())
         {
-            if (keys.dim != ae.keys.dim)
+            if (keys.length != ae.keys.length)
                 return false;
             size_t count = 0;
             foreach (i, key; *keys)
@@ -3143,7 +3161,7 @@ extern (C++) final class AssocArrayLiteralExp : Expression
                     }
                 }
             }
-            return count == keys.dim;
+            return count == keys.length;
         }
         return false;
     }
@@ -3155,7 +3173,7 @@ extern (C++) final class AssocArrayLiteralExp : Expression
 
     override Optional!bool toBool()
     {
-        size_t dim = keys.dim;
+        size_t dim = keys.length;
         return typeof(return)(dim != 0);
     }
 
@@ -3232,7 +3250,7 @@ extern (C++) final class StructLiteralExp : Expression
         {
             if (!type.equals(se.type))
                 return false;
-            if (elements.dim != se.elements.dim)
+            if (elements.length != se.elements.length)
                 return false;
             foreach (i, e1; *elements)
             {
@@ -3269,7 +3287,7 @@ extern (C++) final class StructLiteralExp : Expression
             if (i >= sd.nonHiddenFields())
                 return null;
 
-            assert(i < elements.dim);
+            assert(i < elements.length);
             e = (*elements)[i];
             if (e)
             {
@@ -3310,7 +3328,7 @@ extern (C++) final class StructLiteralExp : Expression
     {
         /* Find which field offset is by looking at the field offsets
          */
-        if (elements.dim)
+        if (elements.length)
         {
             const sz = type.size();
             if (sz == SIZE_INVALID)
@@ -3797,7 +3815,7 @@ extern (C++) final class FuncExp : Expression
         if (td)
         {
             assert(td.literal);
-            assert(td.members && td.members.dim == 1);
+            assert(td.members && td.members.length == 1);
             fd = (*td.members)[0].isFuncLiteralDeclaration();
         }
         tok = fd.tok; // save original kind of function/delegate/(infer)
@@ -3928,7 +3946,7 @@ extern (C++) final class FuncExp : Expression
                 return cannotInfer(this, to, flag);
 
             auto tiargs = new Objects();
-            tiargs.reserve(td.parameters.dim);
+            tiargs.reserve(td.parameters.length);
 
             foreach (tp; *td.parameters)
             {
@@ -4211,7 +4229,7 @@ extern (C++) final class IsExp : Expression
         TemplateParameters* p = null;
         if (parameters)
         {
-            p = new TemplateParameters(parameters.dim);
+            p = new TemplateParameters(parameters.length);
             foreach (i, el; *parameters)
                 (*p)[i] = el.syntaxCopy();
         }
@@ -4655,7 +4673,7 @@ extern (C++) final class MixinExp : Expression
             return false;
         if (auto ce = e.isMixinExp())
         {
-            if (exps.dim != ce.exps.dim)
+            if (exps.length != ce.exps.length)
                 return false;
             foreach (i, e1; *exps)
             {
@@ -4846,7 +4864,7 @@ extern (C++) final class DotVarExp : UnaExp
             if (VarDeclaration vd = var.isVarDeclaration())
             {
                 auto ad = vd.isMember2();
-                if (ad && ad.fields.dim == sc.ctorflow.fieldinit.length)
+                if (ad && ad.fields.length == sc.ctorflow.fieldinit.length)
                 {
                     foreach (i, f; ad.fields)
                     {
diff --git a/gcc/d/dmd/expressionsem.d b/gcc/d/dmd/expressionsem.d
index f899bd79d20..60b51cbc44e 100644
--- a/gcc/d/dmd/expressionsem.d
+++ b/gcc/d/dmd/expressionsem.d
@@ -220,7 +220,7 @@ Expression resolveOpDollar(Scope* sc, ArrayExp ae, Expression* pe0)
         if (e.op == EXP.interval && !(slice && slice.isTemplateDeclaration()))
         {
         Lfallback:
-            if (ae.arguments.dim == 1)
+            if (ae.arguments.length == 1)
                 return null;
             ae.error("multi-dimensional slicing requires template `opSlice`");
             return ErrorExp.get();
@@ -534,7 +534,7 @@ private Expression resolveUFCS(Scope* sc, CallExp ce)
                 /* Transform:
                  *  aa.remove(arg) into delete aa[arg]
                  */
-                if (!ce.arguments || ce.arguments.dim != 1)
+                if (!ce.arguments || ce.arguments.length != 1)
                 {
                     ce.error("expected key as argument to `aa.remove()`");
                     return ErrorExp.get();
@@ -1189,7 +1189,7 @@ private Expression resolvePropertiesX(Scope* sc, Expression e1, Expression e2 =
             Expressions a;
             a.push(e2);
 
-            for (size_t i = 0; i < os.a.dim; i++)
+            for (size_t i = 0; i < os.a.length; i++)
             {
                 if (FuncDeclaration f = resolveFuncCall(loc, sc, os.a[i], tiargs, tthis, &a, FuncResolveFlag.quiet))
                 {
@@ -1206,7 +1206,7 @@ private Expression resolvePropertiesX(Scope* sc, Expression e1, Expression e2 =
             }
         }
         {
-            for (size_t i = 0; i < os.a.dim; i++)
+            for (size_t i = 0; i < os.a.length; i++)
             {
                 if (FuncDeclaration f = resolveFuncCall(loc, sc, os.a[i], tiargs, tthis, null, FuncResolveFlag.quiet))
                 {
@@ -1439,7 +1439,7 @@ private Type arrayExpressionToCommonType(Scope* sc, ref Expressions exps)
     Expression e0 = null;
     bool foundType;
 
-    for (size_t i = 0; i < exps.dim; i++)
+    for (size_t i = 0; i < exps.length; i++)
     {
         Expression e = exps[i];
         if (!e)
@@ -1506,7 +1506,7 @@ private Type arrayExpressionToCommonType(Scope* sc, ref Expressions exps)
     if (t0.ty == Terror)
         return null;
 
-    for (size_t i = 0; i < exps.dim; i++)
+    for (size_t i = 0; i < exps.length; i++)
     {
         Expression e = exps[i];
         if (!e)
@@ -1633,7 +1633,7 @@ private bool preFunctionParameters(Scope* sc, Expressions* exps, const bool repo
     {
         expandTuples(exps);
 
-        for (size_t i = 0; i < exps.dim; i++)
+        for (size_t i = 0; i < exps.length; i++)
         {
             Expression arg = (*exps)[i];
             arg = resolveProperties(sc, arg);
@@ -1721,7 +1721,7 @@ private bool functionParameters(const ref Loc loc, Scope* sc,
     //printf("functionParameters() %s\n", fd ? fd.toChars() : "");
     assert(arguments);
     assert(fd || tf.next);
-    size_t nargs = arguments ? arguments.dim : 0;
+    size_t nargs = arguments ? arguments.length : 0;
     const size_t nparams = tf.parameterList.length;
     const olderrors = global.errors;
     bool err = false;
@@ -1843,7 +1843,7 @@ private bool functionParameters(const ref Loc loc, Scope* sc,
                         Type tret = p.isLazyArray();
 
                         auto elements = new Expressions(nargs - i);
-                        foreach (u; 0 .. elements.dim)
+                        foreach (u; 0 .. elements.length)
                         {
                             Expression a = (*arguments)[i + u];
                             if (tret && a.implicitConvTo(tret))
@@ -2085,7 +2085,7 @@ private bool functionParameters(const ref Loc loc, Scope* sc,
                  * Check arg to see if it matters.
                  */
                 VarDeclaration vPar = fd ? (fd.parameters ? (*fd.parameters)[i] : null) : null;
-                err |= checkParamArgumentEscape(sc, fd, p, vPar, cast(STC) pStc, arg, false, false);
+                err |= checkParamArgumentEscape(sc, fd, p.ident, vPar, cast(STC) pStc, arg, false, false);
             }
 
             // Turning heap allocations into stack allocations is dangerous without dip1000, since `scope` inference
@@ -2451,10 +2451,10 @@ private bool functionParameters(const ref Loc loc, Scope* sc,
     // If D linkage and variadic, add _arguments[] as first argument
     if (tf.isDstyleVariadic())
     {
-        assert(arguments.dim >= nparams);
+        assert(arguments.length >= nparams);
 
-        auto args = new Parameters(arguments.dim - nparams);
-        for (size_t i = 0; i < arguments.dim - nparams; i++)
+        auto args = new Parameters(arguments.length - nparams);
+        for (size_t i = 0; i < arguments.length - nparams; i++)
         {
             auto arg = new Parameter(STC.in_, (*arguments)[nparams + i].type, null, null, null);
             (*args)[i] = arg;
@@ -3109,7 +3109,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
 
         // Run semantic() on each argument
         bool err = false;
-        for (size_t i = 0; i < exp.exps.dim; i++)
+        for (size_t i = 0; i < exp.exps.length; i++)
         {
             Expression e = (*exp.exps)[i];
             e = e.expressionSemantic(sc);
@@ -3169,7 +3169,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
 
         /* Disallow array literals of type void being used.
          */
-        if (e.elements.dim > 0 && t0.ty == Tvoid)
+        if (e.elements.length > 0 && t0.ty == Tvoid)
         {
             e.error("`%s` of type `%s` has no value", e.toChars(), e.type.toChars());
             return setError();
@@ -3201,10 +3201,10 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
 
         expandTuples(e.keys);
         expandTuples(e.values);
-        if (e.keys.dim != e.values.dim)
+        if (e.keys.length != e.values.length)
         {
             e.error("number of keys is %llu, must match number of values %llu",
-                        cast(ulong) e.keys.dim, cast(ulong) e.values.dim);
+                        cast(ulong) e.keys.length, cast(ulong) e.values.length);
             return setError();
         }
 
@@ -3263,7 +3263,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
             return setError();
         }
 
-        if (checkFrameAccess(e.loc, sc, e.sd, e.elements.dim))
+        if (checkFrameAccess(e.loc, sc, e.sd, e.elements.length))
             return setError();
 
         e.type = e.stype ? e.stype : e.sd.type;
@@ -3579,7 +3579,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
             return setError();
         }
 
-        const size_t nargs = exp.arguments ? exp.arguments.dim : 0;
+        const size_t nargs = exp.arguments ? exp.arguments.length : 0;
         Expression newprefix = null;
 
         if (auto tc = tb.isTypeClass())
@@ -3605,7 +3605,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
             if (cd.isAbstract())
             {
                 exp.error("cannot create instance of abstract class `%s`", cd.toChars());
-                for (size_t i = 0; i < cd.vtbl.dim; i++)
+                for (size_t i = 0; i < cd.vtbl.length; i++)
                 {
                     FuncDeclaration fd = cd.vtbl[i].isFuncDeclaration();
                     if (fd && fd.isAbstract())
@@ -3836,7 +3836,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
                 exp.member = f.isCtorDeclaration();
                 assert(exp.member);
 
-                if (checkFrameAccess(exp.loc, sc, sd, sd.fields.dim))
+                if (checkFrameAccess(exp.loc, sc, sd, sd.fields.length))
                     return setError();
             }
             else
@@ -3850,7 +3850,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
                 if (!sd.fill(exp.loc, *exp.arguments, false))
                     return setError();
 
-                if (checkFrameAccess(exp.loc, sc, sd, exp.arguments ? exp.arguments.dim : 0))
+                if (checkFrameAccess(exp.loc, sc, sd, exp.arguments ? exp.arguments.length : 0))
                     return setError();
 
                 /* Since a `new` allocation may escape, check each of the arguments for escaping
@@ -4113,7 +4113,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
         //printf("td = %p, treq = %p\n", td, fd.treq);
         if (exp.td)
         {
-            assert(exp.td.parameters && exp.td.parameters.dim);
+            assert(exp.td.parameters && exp.td.parameters.length);
             exp.td.dsymbolSemantic(sc);
             exp.type = Type.tvoid; // temporary type
 
@@ -4199,9 +4199,9 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
      */
     Expression callExpSemantic(FuncExp exp, Scope* sc, Expressions* arguments)
     {
-        if ((!exp.type || exp.type == Type.tvoid) && exp.td && arguments && arguments.dim)
+        if ((!exp.type || exp.type == Type.tvoid) && exp.td && arguments && arguments.length)
         {
-            for (size_t k = 0; k < arguments.dim; k++)
+            for (size_t k = 0; k < arguments.length; k++)
             {
                 Expression checkarg = (*arguments)[k];
                 if (checkarg.op == EXP.error)
@@ -4210,21 +4210,21 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
 
             exp.genIdent(sc);
 
-            assert(exp.td.parameters && exp.td.parameters.dim);
+            assert(exp.td.parameters && exp.td.parameters.length);
             exp.td.dsymbolSemantic(sc);
 
             TypeFunction tfl = cast(TypeFunction)exp.fd.type;
             size_t dim = tfl.parameterList.length;
-            if (arguments.dim < dim)
+            if (arguments.length < dim)
             {
                 // Default arguments are always typed, so they don't need inference.
-                Parameter p = tfl.parameterList[arguments.dim];
+                Parameter p = tfl.parameterList[arguments.length];
                 if (p.defaultArg)
-                    dim = arguments.dim;
+                    dim = arguments.length;
             }
 
-            if ((tfl.parameterList.varargs == VarArg.none && arguments.dim > dim) ||
-                arguments.dim < dim)
+            if ((tfl.parameterList.varargs == VarArg.none && arguments.length > dim) ||
+                arguments.length < dim)
             {
                 OutBuffer buf;
                 foreach (idx, ref arg; *arguments)
@@ -4232,16 +4232,16 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
                 exp.error("function literal `%s%s` is not callable using argument types `(%s)`",
                           exp.fd.toChars(), parametersTypeToChars(tfl.parameterList),
                           buf.peekChars());
-                exp.errorSupplemental("too %s arguments, expected `%d`, got `%d`",
-                                      arguments.dim < dim ? "few".ptr : "many".ptr,
-                                      cast(int)dim, cast(int)arguments.dim);
+                exp.errorSupplemental("too %s arguments, expected %d, got %d",
+                                      arguments.length < dim ? "few".ptr : "many".ptr,
+                                      cast(int)dim, cast(int)arguments.length);
                 return ErrorExp.get();
             }
 
             auto tiargs = new Objects();
-            tiargs.reserve(exp.td.parameters.dim);
+            tiargs.reserve(exp.td.parameters.length);
 
-            for (size_t i = 0; i < exp.td.parameters.dim; i++)
+            for (size_t i = 0; i < exp.td.parameters.length; i++)
             {
                 TemplateParameter tp = (*exp.td.parameters)[i];
                 assert(dim <= tfl.parameterList.length);
@@ -4571,7 +4571,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
                 // First look for constructor
                 if (exp.e1.op == EXP.type && sd.ctor)
                 {
-                    if (!sd.noDefaultCtor && !(exp.arguments && exp.arguments.dim))
+                    if (!sd.noDefaultCtor && !(exp.arguments && exp.arguments.length))
                         goto Lx;
 
                     /* https://issues.dlang.org/show_bug.cgi?id=20695
@@ -4587,7 +4587,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
                     auto sle = new StructLiteralExp(exp.loc, sd, null, exp.e1.type);
                     if (!sd.fill(exp.loc, *sle.elements, true))
                         return setError();
-                    if (checkFrameAccess(exp.loc, sc, sd, sle.elements.dim))
+                    if (checkFrameAccess(exp.loc, sc, sd, sle.elements.length))
                         return setError();
 
                     // https://issues.dlang.org/show_bug.cgi?id=14556
@@ -4664,11 +4664,11 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
                     t1 = exp.e1.type;
                 }
 
-                if (!exp.arguments || exp.arguments.dim == 0)
+                if (!exp.arguments || exp.arguments.length == 0)
                 {
                     e = t1.defaultInitLiteral(exp.loc);
                 }
-                else if (exp.arguments.dim == 1)
+                else if (exp.arguments.length == 1)
                 {
                     e = (*exp.arguments)[0];
                     if (!e.type.isTypeNoreturn())
@@ -4685,7 +4685,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
             }
         }
 
-        static FuncDeclaration resolveOverloadSet(Loc loc, Scope* sc,
+        FuncDeclaration resolveOverloadSet(Loc loc, Scope* sc,
             OverloadSet os, Objects* tiargs, Type tthis, Expressions* arguments)
         {
             FuncDeclaration f = null;
@@ -4709,7 +4709,21 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
                 }
             }
             if (!f)
-                .error(loc, "no overload matches for `%s`", os.toChars());
+            {
+                .error(loc, "no overload matches for `%s`", exp.toChars());
+                errorSupplemental(loc, "Candidates are:");
+                foreach (s; os.a)
+                {
+                    overloadApply(s, (ds){
+                        if (auto fd = ds.isFuncDeclaration())
+                            .errorSupplemental(ds.loc, "%s%s", fd.toChars(),
+                                fd.type.toTypeFunction().parameterList.parametersTypeToChars());
+                        else
+                            .errorSupplemental(ds.loc, "%s", ds.toChars());
+                        return 0;
+                    });
+                }
+            }
             else if (f.errors)
                 f = null;
             return f;
@@ -4751,7 +4765,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
                 auto ad2 = b.sym;
                 ue.e1 = ue.e1.castTo(sc, ad2.type.addMod(ue.e1.type.mod));
                 ue.e1 = ue.e1.expressionSemantic(sc);
-                auto vi = exp.f.findVtblIndex(&ad2.vtbl, cast(int)ad2.vtbl.dim);
+                auto vi = exp.f.findVtblIndex(&ad2.vtbl, cast(int)ad2.vtbl.length);
                 assert(vi >= 0);
                 exp.f = ad2.vtbl[vi].isFuncDeclaration();
                 assert(exp.f);
@@ -4769,7 +4783,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
                 tthis = ue.e1.type;
                 if (!(exp.f.type.ty == Tfunction && (cast(TypeFunction)exp.f.type).isScopeQual))
                 {
-                    if (checkParamArgumentEscape(sc, exp.f, null, null, STC.undefined_, ethis, false, false))
+                    if (checkParamArgumentEscape(sc, exp.f, Id.This, exp.f.vthis, STC.undefined_, ethis, false, false))
                         return setError();
                 }
             }
@@ -5283,7 +5297,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
             AttribDeclaration ad = s.isAttribDeclaration();
             if (ad)
             {
-                if (ad.decl && ad.decl.dim == 1)
+                if (ad.decl && ad.decl.length == 1)
                 {
                     s = (*ad.decl)[0];
                     continue;
@@ -5683,10 +5697,10 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
                 {
                     ClassDeclaration cd = (cast(TypeClass)e.targ).sym;
                     auto args = new Parameters();
-                    args.reserve(cd.baseclasses.dim);
+                    args.reserve(cd.baseclasses.length);
                     if (cd.semanticRun < PASS.semanticdone)
                         cd.dsymbolSemantic(null);
-                    for (size_t i = 0; i < cd.baseclasses.dim; i++)
+                    for (size_t i = 0; i < cd.baseclasses.length; i++)
                     {
                         BaseClass* b = (*cd.baseclasses)[i];
                         args.push(new Parameter(STC.in_, b.type, null, null, null));
@@ -5775,7 +5789,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
                 return yes();
             return no();
         }
-        else if (e.tspec && !e.id && !(e.parameters && e.parameters.dim))
+        else if (e.tspec && !e.id && !(e.parameters && e.parameters.length))
         {
             /* Evaluate to true if targ matches tspec
              * is(targ == tspec)
@@ -5833,7 +5847,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
             Identifier tid = e.id ? e.id : Identifier.generateId("__isexp_id");
             e.parameters.insert(0, new TemplateTypeParameter(e.loc, tid, null, null));
 
-            Objects dedtypes = Objects(e.parameters.dim);
+            Objects dedtypes = Objects(e.parameters.length);
             dedtypes.zero();
 
             MATCH m = deduceType(e.targ, sc, e.tspec, e.parameters, &dedtypes, null, 0, e.tok == TOK.equal);
@@ -5853,7 +5867,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
 
                 /* Declare trailing parameters
                  */
-                for (size_t i = 1; i < e.parameters.dim; i++)
+                for (size_t i = 1; i < e.parameters.length; i++)
                 {
                     TemplateParameter tp = (*e.parameters)[i];
                     Declaration s = null;
@@ -6502,13 +6516,10 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
                 result = expressionSemantic(e, sc);
                 return;
             }
-        }
 
-        if (exp.arrow) // ImportC only
-            exp.e1 = exp.e1.expressionSemantic(sc).arrayFuncConv(sc);
+            if (exp.arrow) // ImportC only
+                exp.e1 = exp.e1.expressionSemantic(sc).arrayFuncConv(sc);
 
-        if (sc.flags & SCOPE.Cfile)
-        {
             if (exp.ident == Id.__xalignof && exp.e1.isTypeExp())
             {
                 // C11 6.5.3 says _Alignof only applies to types
@@ -6538,12 +6549,12 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
                     assert(0);
                 return;
             }
-        }
 
-        if (sc.flags & SCOPE.Cfile && exp.ident != Id.__sizeof)
-        {
-            result = fieldLookup(exp.e1, sc, exp.ident);
-            return;
+            if (exp.ident != Id.__sizeof)
+            {
+                result = fieldLookup(exp.e1, sc, exp.ident);
+                return;
+            }
         }
 
         Expression e = exp.semanticY(sc, 1);
@@ -6618,8 +6629,8 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
             Expression ev = sc.func ? extractSideEffect(sc, "__tup", e0, exp.e1) : exp.e1;
 
             auto exps = new Expressions();
-            exps.reserve(tup.objects.dim);
-            for (size_t i = 0; i < tup.objects.dim; i++)
+            exps.reserve(tup.objects.length);
+            for (size_t i = 0; i < tup.objects.length; i++)
             {
                 RootObject o = (*tup.objects)[i];
                 Expression e;
@@ -7560,7 +7571,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
                 }
             }
             TupleExp te = exp.e1.isTupleExp();
-            if (te.exps.dim == 1)
+            if (te.exps.length == 1)
                 exp.e1 = (*te.exps)[0];
         }
 
@@ -7646,14 +7657,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
         // Check for unsafe casts
         if (!isSafeCast(ex, t1b, tob))
         {
-            // This is an ad-hoc fix for https://issues.dlang.org/show_bug.cgi?id=19646
-            // Should be replaced by a more general @system variables implementation
-            if (!sc.func && sc.stc & STC.safe)
-            {
-                exp.error("cast from `%s` to `%s` not allowed in safe code", exp.e1.type.toChars(), exp.to.toChars());
-                return setError();
-            }
-
             if (sc.setUnsafe(false, exp.loc, "cast from `%s` to `%s` not allowed in safe code", exp.e1.type, exp.to))
             {
                 return setError();
@@ -8000,7 +8003,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
             {
                 te = cast(TupleExp)exp.e1;
                 tup = null;
-                length = te.exps.dim;
+                length = te.exps.length;
             }
             else if (exp.e1.op == EXP.type) // slicing a type tuple
             {
@@ -8403,7 +8406,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
         if (exp.e2.op == EXP.tuple)
         {
             TupleExp te = cast(TupleExp)exp.e2;
-            if (te.exps && te.exps.dim == 1)
+            if (te.exps && te.exps.length == 1)
                 exp.e2 = Expression.combine(te.e0, (*te.exps)[0]); // bug 4444 fix
         }
         if (sc != scx)
@@ -8467,6 +8470,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
                 }
 
                 semanticTypeInfo(sc, taa);
+                checkNewEscape(sc, exp.e2, false);
 
                 exp.type = taa.next;
                 break;
@@ -8487,7 +8491,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
                 {
                     te = cast(TupleExp)exp.e1;
                     tup = null;
-                    length = te.exps.dim;
+                    length = te.exps.length;
                 }
                 else if (exp.e1.op == EXP.type)
                 {
@@ -8710,7 +8714,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
             auto sle = new StructLiteralExp(loc, sd, null, t);
             if (!sd.fill(loc, *sle.elements, true))
                 return ErrorExp.get();
-            if (checkFrameAccess(loc, sc, sd, sle.elements.dim))
+            if (checkFrameAccess(loc, sc, sd, sle.elements.length))
                 return ErrorExp.get();
 
             sle.type = t;
@@ -8769,11 +8773,11 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
             Expression ae1old = ae.e1;
 
             const(bool) maybeSlice =
-                (ae.arguments.dim == 0 ||
-                 ae.arguments.dim == 1 && (*ae.arguments)[0].op == EXP.interval);
+                (ae.arguments.length == 0 ||
+                 ae.arguments.length == 1 && (*ae.arguments)[0].op == EXP.interval);
 
             IntervalExp ie = null;
-            if (maybeSlice && ae.arguments.dim)
+            if (maybeSlice && ae.arguments.length)
             {
                 assert((*ae.arguments)[0].op == EXP.interval);
                 ie = cast(IntervalExp)(*ae.arguments)[0];
@@ -8983,11 +8987,11 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
             {
                 TupleExp tup1 = cast(TupleExp)exp.e1;
                 TupleExp tup2 = cast(TupleExp)e2x;
-                size_t dim = tup1.exps.dim;
+                size_t dim = tup1.exps.length;
                 Expression e = null;
-                if (dim != tup2.exps.dim)
+                if (dim != tup2.exps.length)
                 {
-                    exp.error("mismatched tuple lengths, %d and %d", cast(int)dim, cast(int)tup2.exps.dim);
+                    exp.error("mismatched tuple lengths, %d and %d", cast(int)dim, cast(int)tup2.exps.length);
                     return setError();
                 }
                 if (dim == 0)
@@ -9026,13 +9030,13 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
 
                 auto iexps = new Expressions();
                 iexps.push(ev);
-                for (size_t u = 0; u < iexps.dim; u++)
+                for (size_t u = 0; u < iexps.length; u++)
                 {
                 Lexpand:
                     Expression e = (*iexps)[u];
 
                     Parameter arg = Parameter.getNth(tt.arguments, u);
-                    //printf("[%d] iexps.dim = %d, ", u, iexps.dim);
+                    //printf("[%d] iexps.length = %d, ", u, iexps.length);
                     //printf("e = (%s %s, %s), ", Token.toChars[e.op], e.toChars(), e.type.toChars());
                     //printf("arg = (%s, %s)\n", arg.toChars(), arg.type.toChars());
 
@@ -9041,7 +9045,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
                         // expand initializer to tuple
                         if (expandAliasThisTuples(iexps, u) != -1)
                         {
-                            if (iexps.dim <= u)
+                            if (iexps.length <= u)
                                 break;
                             goto Lexpand;
                         }
@@ -9527,7 +9531,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
                     uinteger_t dim2 = dim1;
                     if (auto ale = e2x.isArrayLiteralExp())
                     {
-                        dim2 = ale.elements ? ale.elements.dim : 0;
+                        dim2 = ale.elements ? ale.elements.length : 0;
                     }
                     else if (auto se = e2x.isSliceExp())
                     {
@@ -9752,7 +9756,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
             TypeSArray tsa1 = cast(TypeSArray)toStaticArrayType(se1);
             TypeSArray tsa2 = null;
             if (auto ale = e2x.isArrayLiteralExp())
-                tsa2 = cast(TypeSArray)t2.nextOf().sarrayOf(ale.elements.dim);
+                tsa2 = cast(TypeSArray)t2.nextOf().sarrayOf(ale.elements.length);
             else if (auto se = e2x.isSliceExp())
                 tsa2 = cast(TypeSArray)toStaticArrayType(se);
             else
@@ -10359,9 +10363,13 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
             return setError();
 
         exp.type = exp.e1.type;
+        auto assignElem = exp.e2;
         auto res = exp.reorderSettingAAElem(sc);
-        if (exp.op == EXP.concatenateElemAssign || exp.op == EXP.concatenateDcharAssign)
+        if (res != exp) // `AA[k] = v` rewrite was performed
+            checkNewEscape(sc, assignElem, false);
+        else if (exp.op == EXP.concatenateElemAssign || exp.op == EXP.concatenateDcharAssign)
             checkAssignEscape(sc, res, false, false);
+
         result = res;
 
         if ((exp.op == EXP.concatenateAssign || exp.op == EXP.concatenateElemAssign) &&
@@ -11917,7 +11925,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
             {
                 static struct Result { bool ttEmpty; bool te; }
                 auto tt = e.op == EXP.type ? e.isTypeExp().type.isTypeTuple() : null;
-                return Result(tt && (!tt.arguments || !tt.arguments.dim), e.isTupleExp() !is null);
+                return Result(tt && (!tt.arguments || !tt.arguments.length), e.isTupleExp() !is null);
             }
             auto tups1 = extractTypeTupAndExpTup(exp.e1);
             auto tups2 = extractTypeTupAndExpTup(exp.e2);
@@ -12599,7 +12607,7 @@ Expression semanticX(DotIdExp exp, Scope* sc)
         {
             /* 'distribute' the .offsetof to each of the tuple elements.
              */
-            auto exps = new Expressions(te.exps.dim);
+            auto exps = new Expressions(te.exps.length);
             foreach (i, e; (*te.exps)[])
             {
                 (*exps)[i] = new DotIdExp(e.loc, e, Id.offsetof);
@@ -12612,7 +12620,7 @@ Expression semanticX(DotIdExp exp, Scope* sc)
         if (exp.ident == Id.length)
         {
             // Don't evaluate te.e0 in runtime
-            return new IntegerExp(exp.loc, te.exps.dim, Type.tsize_t);
+            return new IntegerExp(exp.loc, te.exps.length, Type.tsize_t);
         }
     }
 
@@ -13564,7 +13572,7 @@ private bool fit(StructDeclaration sd, const ref Loc loc, Scope* sc, Expressions
 
     const nfields = sd.nonHiddenFields();
     size_t offset = 0;
-    for (size_t i = 0; i < elements.dim; i++)
+    for (size_t i = 0; i < elements.length; i++)
     {
         Expression e = (*elements)[i];
         if (!e)
@@ -13573,7 +13581,7 @@ private bool fit(StructDeclaration sd, const ref Loc loc, Scope* sc, Expressions
         e = resolveProperties(sc, e);
         if (i >= nfields)
         {
-            if (i < sd.fields.dim && e.op == EXP.null_)
+            if (i < sd.fields.length && e.op == EXP.null_)
             {
                 // CTFE sometimes creates null as hidden pointer; we'll allow this.
                 continue;
diff --git a/gcc/d/dmd/file_manager.d b/gcc/d/dmd/file_manager.d
index 0ea73036a78..a941115acc4 100644
--- a/gcc/d/dmd/file_manager.d
+++ b/gcc/d/dmd/file_manager.d
@@ -12,7 +12,7 @@ module dmd.file_manager;
 
 import dmd.root.stringtable : StringTable;
 import dmd.root.file : File, Buffer;
-import dmd.root.filename : FileName;
+import dmd.root.filename : FileName, isDirSeparator;
 import dmd.root.string : toDString;
 import dmd.globals;
 import dmd.identifier;
@@ -26,14 +26,86 @@ bool isPackageFileName(scope FileName fileName) nothrow
     return FileName.equals(fileName.name, package_d) || FileName.equals(fileName.name, package_di);
 }
 
+// A path stack that allows one to go up and down the path using directory
+// separators. `cur` is the current path, `up` goes up one path, `down` goes
+// down one path. if `up` or `down` return false, there are no further paths.
+private struct PathStack
+{
+    private const(char)[] path;
+    private size_t pos;
+
+    @safe @nogc nothrow pure:
+
+    this(const(char)[] p)
+    {
+        path = p;
+        pos = p.length;
+    }
+
+    const(char)[] cur()
+    {
+        return path[0 .. pos];
+    }
+
+    bool up()
+    {
+        if (pos == 0)
+            return false;
+        while (--pos != 0)
+            if (isDirSeparator(path[pos]))
+                return true;
+        return false;
+    }
+
+    bool down()
+    {
+        if (pos == path.length)
+            return false;
+        while (++pos != path.length)
+            if (isDirSeparator(path[pos]))
+                return true;
+        return false;
+    }
+}
+
 final class FileManager
 {
     private StringTable!(const(ubyte)[]) files;
+    private StringTable!(bool) packageStatus;
+
+    // check if the package path of the given path exists. The input path is
+    // expected to contain the full path to the module, so the parent
+    // directories of that path are checked.
+    private bool packageExists(const(char)[] p) nothrow
+    {
+        // step 1, look for the closest parent path that is cached
+        bool exists = true;
+        auto st = PathStack(p);
+        while (st.up) {
+            if (auto cached = packageStatus.lookup(st.cur)) {
+                exists = cached.value;
+                break;
+            }
+        }
+        // found a parent that is cached (or reached the end of the stack).
+        // step 2, traverse back up the stack storing either false if the
+        // parent doesn't exist, or the result of the `exists` call if it does.
+        while (st.down) {
+            if (!exists)
+                packageStatus.insert(st.cur, false);
+            else
+                exists = packageStatus.insert(st.cur, FileName.exists(st.cur) == 2).value;
+        }
+
+        // at this point, exists should be the answer.
+        return exists;
+    }
 
     ///
     public this () nothrow
     {
         this.files._init();
+        this.packageStatus._init();
     }
 
 nothrow:
@@ -48,13 +120,15 @@ nothrow:
     *      the found file name or
     *      `null` if it is not different from filename.
     */
-    static const(char)[] lookForSourceFile(const char[] filename, const char*[] path)
+    const(char)[] lookForSourceFile(const char[] filename, const char*[] path)
     {
         //printf("lookForSourceFile(`%.*s`)\n", cast(int)filename.length, filename.ptr);
         /* Search along path[] for .di file, then .d file, then .i file, then .c file.
         */
+        // see if we should check for the module locally.
+        bool checkLocal = packageExists(filename);
         const sdi = FileName.forceExt(filename, hdr_ext);
-        if (FileName.exists(sdi) == 1)
+        if (checkLocal && FileName.exists(sdi) == 1)
             return sdi;
         scope(exit) FileName.free(sdi.ptr);
 
@@ -62,36 +136,43 @@ nothrow:
         // Special file name representing `stdin`, always assume its presence
         if (sd == "__stdin.d")
             return sd;
-        if (FileName.exists(sd) == 1)
+        if (checkLocal && FileName.exists(sd) == 1)
             return sd;
         scope(exit) FileName.free(sd.ptr);
 
         const si = FileName.forceExt(filename, i_ext);
-        if (FileName.exists(si) == 1)
+        if (checkLocal && FileName.exists(si) == 1)
             return si;
         scope(exit) FileName.free(si.ptr);
 
         const sc = FileName.forceExt(filename, c_ext);
-        if (FileName.exists(sc) == 1)
+        if (checkLocal && FileName.exists(sc) == 1)
             return sc;
         scope(exit) FileName.free(sc.ptr);
 
-        if (FileName.exists(filename) == 2)
+        if (checkLocal)
         {
-            /* The filename exists and it's a directory.
-            * Therefore, the result should be: filename/package.d
-            * iff filename/package.d is a file
-            */
-            const ni = FileName.combine(filename, package_di);
-            if (FileName.exists(ni) == 1)
-                return ni;
-            FileName.free(ni.ptr);
-
-            const n = FileName.combine(filename, package_d);
-            if (FileName.exists(n) == 1)
-                return n;
-            FileName.free(n.ptr);
+            auto cached = packageStatus.lookup(filename);
+            if (!cached)
+                cached = packageStatus.insert(filename, FileName.exists(filename) == 2);
+            if (cached.value)
+            {
+                /* The filename exists and it's a directory.
+                 * Therefore, the result should be: filename/package.d
+                 * iff filename/package.d is a file
+                 */
+                const ni = FileName.combine(filename, package_di);
+                if (FileName.exists(ni) == 1)
+                    return ni;
+                FileName.free(ni.ptr);
+
+                const n = FileName.combine(filename, package_d);
+                if (FileName.exists(n) == 1)
+                    return n;
+                FileName.free(n.ptr);
+            }
         }
+
         if (FileName.absolute(filename))
             return null;
         if (!path.length)
@@ -101,6 +182,11 @@ nothrow:
             const p = entry.toDString();
 
             const(char)[] n = FileName.combine(p, sdi);
+
+            if (!packageExists(n)) {
+                FileName.free(n.ptr);
+                continue; // no need to check for anything else.
+            }
             if (FileName.exists(n) == 1) {
                 return n;
             }
@@ -127,7 +213,16 @@ nothrow:
             const b = FileName.removeExt(filename);
             n = FileName.combine(p, b);
             FileName.free(b.ptr);
-            if (FileName.exists(n) == 2)
+
+            scope(exit) FileName.free(n.ptr);
+
+            // also cache this if we are looking for package.d[i]
+            auto cached = packageStatus.lookup(n);
+            if (!cached) {
+                cached = packageStatus.insert(n, FileName.exists(n) == 2);
+            }
+
+            if (cached.value)
             {
                 const n2i = FileName.combine(n, package_di);
                 if (FileName.exists(n2i) == 1)
@@ -139,7 +234,6 @@ nothrow:
                 }
                 FileName.free(n2.ptr);
             }
-            FileName.free(n.ptr);
         }
         return null;
     }
diff --git a/gcc/d/dmd/func.d b/gcc/d/dmd/func.d
index 3b0b34e603d..93e36343721 100644
--- a/gcc/d/dmd/func.d
+++ b/gcc/d/dmd/func.d
@@ -640,7 +640,7 @@ extern (C++) class FuncDeclaration : Declaration
     }
 
     /*************************************************
-     * Find index of function in vtbl[0..dim] that
+     * Find index of function in vtbl[0..length] that
      * this function overrides.
      * Prefer an exact match to a covariant one.
      * Params:
@@ -777,7 +777,7 @@ extern (C++) class FuncDeclaration : Declaration
         {
             foreach (b; cd.interfaces)
             {
-                auto v = findVtblIndex(&b.sym.vtbl, cast(int)b.sym.vtbl.dim);
+                auto v = findVtblIndex(&b.sym.vtbl, cast(int)b.sym.vtbl.length);
                 if (v >= 0)
                     return b;
             }
@@ -1810,7 +1810,7 @@ extern (C++) class FuncDeclaration : Declaration
         if (!isVirtual())
             return false;
         // If it's a final method, and does not override anything, then it is not virtual
-        if (isFinalFunc() && foverrides.dim == 0)
+        if (isFinalFunc() && foverrides.length == 0)
         {
             return false;
         }
@@ -1967,7 +1967,7 @@ extern (C++) class FuncDeclaration : Declaration
                 if (fdthis != this)
                 {
                     bool found = false;
-                    for (size_t i = 0; i < siblingCallers.dim; ++i)
+                    for (size_t i = 0; i < siblingCallers.length; ++i)
                     {
                         if (siblingCallers[i] == fdthis)
                             found = true;
@@ -2033,12 +2033,12 @@ extern (C++) class FuncDeclaration : Declaration
         if (requiresClosure)
             goto Lyes;
 
-        for (size_t i = 0; i < closureVars.dim; i++)
+        for (size_t i = 0; i < closureVars.length; i++)
         {
             VarDeclaration v = closureVars[i];
             //printf("\tv = %s\n", v.toChars());
 
-            for (size_t j = 0; j < v.nestedrefs.dim; j++)
+            for (size_t j = 0; j < v.nestedrefs.length; j++)
             {
                 FuncDeclaration f = v.nestedrefs[j];
                 assert(f != this);
@@ -2167,7 +2167,7 @@ extern (C++) class FuncDeclaration : Declaration
      */
     final bool hasNestedFrameRefs()
     {
-        if (closureVars.dim)
+        if (closureVars.length)
             return true;
 
         /* If a virtual function has contracts, assume its variables are referenced
@@ -2181,9 +2181,9 @@ extern (C++) class FuncDeclaration : Declaration
         if (fdrequire || fdensure)
             return true;
 
-        if (foverrides.dim && isVirtualMethod())
+        if (foverrides.length && isVirtualMethod())
         {
-            for (size_t i = 0; i < foverrides.dim; i++)
+            for (size_t i = 0; i < foverrides.length; i++)
             {
                 FuncDeclaration fdv = foverrides[i];
                 if (fdv.hasNestedFrameRefs())
@@ -2406,7 +2406,7 @@ extern (C++) class FuncDeclaration : Declaration
              * becomes:
              *   in { { statements1... } { statements2... } ... }
              */
-            assert(frequires.dim);
+            assert(frequires.length);
             auto loc = (*frequires)[0].loc;
             auto s = new Statements;
             foreach (r; *frequires)
@@ -2425,7 +2425,7 @@ extern (C++) class FuncDeclaration : Declaration
              *   out(__result) { { ref id1 = __result; { statements1... } }
              *                   { ref id2 = __result; { statements2... } } ... }
              */
-            assert(fensures.dim);
+            assert(fensures.length);
             auto loc = (*fensures)[0].ensure.loc;
             auto s = new Statements;
             foreach (r; *fensures)
@@ -3133,7 +3133,7 @@ FuncDeclaration resolveFuncCall(const ref Loc loc, Scope* sc, Dsymbol s,
             printf("\tthis: %s\n", tthis.toChars());
         if (fargs)
         {
-            for (size_t i = 0; i < fargs.dim; i++)
+            for (size_t i = 0; i < fargs.length; i++)
             {
                 Expression arg = (*fargs)[i];
                 assert(arg.type);
@@ -3352,46 +3352,40 @@ if (is(Decl == TemplateDeclaration) || is(Decl == FuncDeclaration))
 {
     // max num of overloads to print (-v overrides this).
     enum int DisplayLimit = 5;
-    int displayed;
     const(char)* constraintsTip;
-
     // determine if the first candidate was printed
-    bool printed = false;
+    int printed;
 
-    overloadApply(declaration, (Dsymbol s)
+    bool matchSymbol(Dsymbol s, bool print, bool single_candidate = false)
     {
-        Dsymbol nextOverload;
-
         if (auto fd = s.isFuncDeclaration())
         {
             // Don't print overloads which have errors.
             // Not that if the whole overload set has errors, we'll never reach
             // this point so there's no risk of printing no candidate
             if (fd.errors || fd.type.ty == Terror)
-                return 0;
+                return false;
             // Don't print disabled functions, or `deprecated` outside of deprecated scope
             if (fd.storage_class & STC.disable || (fd.isDeprecated() && !showDeprecated))
-                return 0;
-
-            const single_candidate = fd.overnext is null;
+                return false;
+            if (!print)
+                return true;
             auto tf = cast(TypeFunction) fd.type;
             .errorSupplemental(fd.loc,
                     printed ? "                `%s%s`" :
                     single_candidate ? "Candidate is: `%s%s`" : "Candidates are: `%s%s`",
                     fd.toPrettyChars(),
                 parametersTypeToChars(tf.parameterList));
-            printed = true;
-            nextOverload = fd.overnext;
         }
         else if (auto td = s.isTemplateDeclaration())
         {
             import dmd.staticcond;
 
+            if (!print)
+                return true;
             const tmsg = td.toCharsNoConstraints();
             const cmsg = td.getConstraintEvalError(constraintsTip);
 
-            const single_candidate = td.overnext is null;
-
             // add blank space if there are multiple candidates
             // the length of the blank space is `strlen("Candidates are: ")`
 
@@ -3401,7 +3395,6 @@ if (is(Decl == TemplateDeclaration) || is(Decl == FuncDeclaration))
                         printed ? "                `%s`\n%s" :
                         single_candidate ? "Candidate is: `%s`\n%s" : "Candidates are: `%s`\n%s",
                         tmsg, cmsg);
-                printed = true;
             }
             else
             {
@@ -3409,26 +3402,38 @@ if (is(Decl == TemplateDeclaration) || is(Decl == FuncDeclaration))
                         printed ? "                `%s`" :
                         single_candidate ? "Candidate is: `%s`" : "Candidates are: `%s`",
                         tmsg);
-                printed = true;
             }
-            nextOverload = td.overnext;
         }
-
-        if (global.params.verbose || ++displayed < DisplayLimit)
-            return 0;
-
-        // Too many overloads to sensibly display.
-        // Just show count of remaining overloads.
-        int num = 0;
-        overloadApply(nextOverload, (s) { ++num; return 0; });
-
-        if (num > 0)
-            .errorSupplemental(loc, "... (%d more, -v to show) ...", num);
-        return 1;   // stop iterating
+        return true;
+    }
+    // determine if there's > 1 candidate
+    int count = 0;
+    overloadApply(declaration, (s) {
+        if (matchSymbol(s, false))
+            count++;
+        return count > 1;
+    });
+    int skipped = 0;
+    overloadApply(declaration, (s) {
+        if (global.params.verbose || printed < DisplayLimit)
+        {
+            if (matchSymbol(s, true, count == 1))
+                printed++;
+        }
+        else
+        {
+            // Too many overloads to sensibly display.
+            // Just show count of remaining overloads.
+            if (matchSymbol(s, false))
+                skipped++;
+        }
+        return 0;
     });
+    if (skipped > 0)
+        .errorSupplemental(loc, "... (%d more, -v to show) ...", skipped);
 
     // Nothing was displayed, all overloads are either disabled or deprecated
-    if (!displayed)
+    if (!printed)
         .errorSupplemental(loc, "All possible candidates are marked as `deprecated` or `@disable`");
     // should be only in verbose mode
     if (constraintsTip)
@@ -3570,7 +3575,7 @@ private void markAsNeedingClosure(Dsymbol f, FuncDeclaration outerFunc)
     for (Dsymbol sx = f; sx && sx != outerFunc; sx = sx.toParentP(outerFunc))
     {
         FuncDeclaration fy = sx.isFuncDeclaration();
-        if (fy && fy.closureVars.dim)
+        if (fy && fy.closureVars.length)
         {
             /* fy needs a closure if it has closureVars[],
              * because the frame pointer in the closure will be accessed.
@@ -3608,7 +3613,7 @@ private bool checkEscapingSiblings(FuncDeclaration f, FuncDeclaration outerFunc,
 
     //printf("checkEscapingSiblings(f = %s, outerfunc = %s)\n", f.toChars(), outerFunc.toChars());
     bool bAnyClosures = false;
-    for (size_t i = 0; i < f.siblingCallers.dim; ++i)
+    for (size_t i = 0; i < f.siblingCallers.length; ++i)
     {
         FuncDeclaration g = f.siblingCallers[i];
         if (g.isThis() || g.tookAddressOf)
@@ -4351,19 +4356,30 @@ bool setUnsafe(Scope* sc,
     bool gag = false, Loc loc = Loc.init, const(char)* fmt = null,
     RootObject arg0 = null, RootObject arg1 = null, RootObject arg2 = null)
 {
-    // TODO:
-    // For @system variables, unsafe initializers at global scope should mark
-    // the variable @system, see https://dlang.org/dips/1035
-
-    if (!sc.func)
-        return false;
-
     if (sc.intypeof)
         return false; // typeof(cast(int*)0) is safe
 
     if (sc.flags & SCOPE.debug_) // debug {} scopes are permissive
         return false;
 
+    if (!sc.func)
+    {
+        if (sc.varDecl)
+        {
+            if (sc.varDecl.storage_class & STC.safe)
+            {
+                .error(loc, fmt, arg0 ? arg0.toChars() : "", arg1 ? arg1.toChars() : "", arg2 ? arg2.toChars() : "");
+                return true;
+            }
+            else if (!(sc.varDecl.storage_class & STC.system))
+            {
+                sc.varDecl.storage_class |= STC.system;
+            }
+        }
+        return false;
+    }
+
+
     if (sc.flags & SCOPE.compile) // __traits(compiles, x)
     {
         if (sc.func.isSafeBypassingInference())
diff --git a/gcc/d/dmd/hdrgen.d b/gcc/d/dmd/hdrgen.d
index debf01d2a8e..6b51a81acc5 100644
--- a/gcc/d/dmd/hdrgen.d
+++ b/gcc/d/dmd/hdrgen.d
@@ -484,7 +484,7 @@ public:
     {
         buf.writestring("pragma (");
         buf.writestring(s.ident.toString());
-        if (s.args && s.args.dim)
+        if (s.args && s.args.length)
         {
             buf.writestring(", ");
             argsToBuffer(s.args, buf, hgs);
@@ -883,7 +883,7 @@ public:
             buf.printf("%s.", pid.toChars());
         }
         buf.writestring(imp.id.toString());
-        if (imp.names.dim)
+        if (imp.names.length)
         {
             buf.writestring(" : ");
             foreach (const i, const name; imp.names)
@@ -922,13 +922,13 @@ public:
             buf.writenl();
             return;
         }
-        if (d.decl.dim == 0 || (hgs.hdrgen && d.decl.dim == 1 && (*d.decl)[0].isUnitTestDeclaration()))
+        if (d.decl.length == 0 || (hgs.hdrgen && d.decl.length == 1 && (*d.decl)[0].isUnitTestDeclaration()))
         {
             // hack for bugzilla 8081
             if (hasSTC) buf.writeByte(' ');
             buf.writestring("{}");
         }
-        else if (d.decl.dim == 1)
+        else if (d.decl.length == 1)
         {
             if (hasSTC) buf.writeByte(' ');
             (*d.decl)[0].accept(this);
@@ -993,9 +993,9 @@ public:
     {
         visibilityToBuffer(buf, d.visibility);
         AttribDeclaration ad = cast(AttribDeclaration)d;
-        if (ad.decl.dim <= 1)
+        if (ad.decl.length <= 1)
             buf.writeByte(' ');
-        if (ad.decl.dim == 1 && (*ad.decl)[0].isVisibilityDeclaration)
+        if (ad.decl.length == 1 && (*ad.decl)[0].isVisibilityDeclaration)
             visit(cast(AttribDeclaration)(*ad.decl)[0]);
         else
             visit(cast(AttribDeclaration)d);
@@ -1011,7 +1011,7 @@ public:
                     buf.writeByte(' ');
                 buf.printf("align (%s)", exp.toChars());
             }
-            if (d.decl && d.decl.dim < 2)
+            if (d.decl && d.decl.length < 2)
                 buf.writeByte(' ');
         }
         else
@@ -1041,7 +1041,7 @@ public:
     {
         buf.writestring("pragma (");
         buf.writestring(d.ident.toString());
-        if (d.args && d.args.dim)
+        if (d.args && d.args.length)
         {
             buf.writestring(", ");
             argsToBuffer(d.args, buf, hgs);
@@ -1210,7 +1210,7 @@ public:
 
     bool visitEponymousMember(TemplateDeclaration d)
     {
-        if (!d.members || d.members.dim != 1)
+        if (!d.members || d.members.length != 1)
             return false;
         Dsymbol onemember = (*d.members)[0];
         if (onemember.ident != d.ident)
@@ -1286,7 +1286,7 @@ public:
 
     void visitTemplateParameters(TemplateParameters* parameters)
     {
-        if (!parameters || !parameters.dim)
+        if (!parameters || !parameters.length)
             return;
         foreach (i, p; *parameters)
         {
@@ -1437,7 +1437,7 @@ public:
 
     void visitBaseClasses(ClassDeclaration d)
     {
-        if (!d || !d.baseclasses.dim)
+        if (!d || !d.baseclasses.length)
             return;
         if (!d.isAnonymous())
             buf.writestring(" : ");
@@ -1722,7 +1722,7 @@ public:
         Statement s1;
         if (f.semanticRun >= PASS.semantic3done && cs)
         {
-            s1 = (*cs.statements)[cs.statements.dim - 1];
+            s1 = (*cs.statements)[cs.statements.length - 1];
         }
         else
             s1 = !cs ? f.fbody : null;
@@ -2130,7 +2130,7 @@ private void expressionPrettyPrint(Expression e, OutBuffer* buf, HdrGenState* hg
         }
         buf.writestring("new ");
         typeToBuffer(e.newtype, null, buf, hgs);
-        if (e.arguments && e.arguments.dim)
+        if (e.arguments && e.arguments.length)
         {
             buf.writeByte('(');
             argsToBuffer(e.arguments, buf, hgs);
@@ -2147,7 +2147,7 @@ private void expressionPrettyPrint(Expression e, OutBuffer* buf, HdrGenState* hg
         }
         buf.writestring("new");
         buf.writestring(" class ");
-        if (e.arguments && e.arguments.dim)
+        if (e.arguments && e.arguments.length)
         {
             buf.writeByte('(');
             argsToBuffer(e.arguments, buf, hgs);
@@ -2271,7 +2271,7 @@ private void expressionPrettyPrint(Expression e, OutBuffer* buf, HdrGenState* hg
                 buf.writestring(" == ");
             typeToBuffer(e.tspec, null, buf, hgs);
         }
-        if (e.parameters && e.parameters.dim)
+        if (e.parameters && e.parameters.length)
         {
             buf.writestring(", ");
             scope v = new DsymbolPrettyPrintVisitor(buf, hgs);
@@ -3100,7 +3100,7 @@ void toCBuffer(const Expression e, OutBuffer* buf, HdrGenState* hgs)
  */
 void argExpTypesToCBuffer(OutBuffer* buf, Expressions* arguments)
 {
-    if (!arguments || !arguments.dim)
+    if (!arguments || !arguments.length)
         return;
     HdrGenState hgs;
     foreach (i, arg; *arguments)
@@ -3119,7 +3119,7 @@ void toCBuffer(const TemplateParameter tp, OutBuffer* buf, HdrGenState* hgs)
 
 void arrayObjectsToBuffer(OutBuffer* buf, Objects* objects)
 {
-    if (!objects || !objects.dim)
+    if (!objects || !objects.length)
         return;
     HdrGenState hgs;
     foreach (i, o; *objects)
@@ -3160,7 +3160,7 @@ const(char)* parameterToChars(Parameter parameter, TypeFunction tf, bool fullQua
 
     parameterToBuffer(parameter, &buf, &hgs);
 
-    if (tf.parameterList.varargs == VarArg.typesafe && parameter == tf.parameterList[tf.parameterList.parameters.dim - 1])
+    if (tf.parameterList.varargs == VarArg.typesafe && parameter == tf.parameterList[tf.parameterList.parameters.length - 1])
     {
         buf.writestring("...");
     }
@@ -3219,7 +3219,7 @@ private void parameterToBuffer(Parameter p, OutBuffer* buf, HdrGenState* hgs)
     {
         buf.writeByte('@');
 
-        bool isAnonymous = p.userAttribDecl.atts.dim > 0 && !(*p.userAttribDecl.atts)[0].isCallExp();
+        bool isAnonymous = p.userAttribDecl.atts.length > 0 && !(*p.userAttribDecl.atts)[0].isCallExp();
         if (isAnonymous)
             buf.writeByte('(');
 
@@ -3281,7 +3281,7 @@ private void parameterToBuffer(Parameter p, OutBuffer* buf, HdrGenState* hgs)
  */
 private void argsToBuffer(Expressions* expressions, OutBuffer* buf, HdrGenState* hgs, Expression basis = null)
 {
-    if (!expressions || !expressions.dim)
+    if (!expressions || !expressions.length)
         return;
     version (all)
     {
@@ -3298,11 +3298,11 @@ private void argsToBuffer(Expressions* expressions, OutBuffer* buf, HdrGenState*
     else
     {
         // Sparse style formatting, for debug use only
-        //      [0..dim: basis, 1: e1, 5: e5]
+        //      [0..length: basis, 1: e1, 5: e5]
         if (basis)
         {
             buf.writestring("0..");
-            buf.print(expressions.dim);
+            buf.print(expressions.length);
             buf.writestring(": ");
             expToBuffer(basis, PREC.assign, buf, hgs);
         }
@@ -3483,12 +3483,12 @@ private void tiargsToBuffer(TemplateInstance ti, OutBuffer* buf, HdrGenState* hg
         buf.writestring("()");
         return;
     }
-    if (ti.tiargs.dim == 1)
+    if (ti.tiargs.length == 1)
     {
         RootObject oarg = (*ti.tiargs)[0];
         if (Type t = isType(oarg))
         {
-            if (t.equals(Type.tstring) || t.equals(Type.twstring) || t.equals(Type.tdstring) || t.mod == 0 && (t.isTypeBasic() || t.ty == Tident && (cast(TypeIdentifier)t).idents.dim == 0))
+            if (t.equals(Type.tstring) || t.equals(Type.twstring) || t.equals(Type.tdstring) || t.mod == 0 && (t.isTypeBasic() || t.ty == Tident && (cast(TypeIdentifier)t).idents.length == 0))
             {
                 buf.writestring(t.toChars());
                 return;
diff --git a/gcc/d/dmd/iasmgcc.d b/gcc/d/dmd/iasmgcc.d
index 7a840ffa585..f85e1ab2518 100644
--- a/gcc/d/dmd/iasmgcc.d
+++ b/gcc/d/dmd/iasmgcc.d
@@ -332,7 +332,7 @@ extern (C++) public Statement gccAsmSemantic(GccAsmStatement s, Scope *sc)
     // Analyse all input and output operands.
     if (s.args)
     {
-        foreach (i; 0 .. s.args.dim)
+        foreach (i; 0 .. s.args.length)
         {
             Expression e = (*s.args)[i];
             e = e.expressionSemantic(sc);
@@ -353,7 +353,7 @@ extern (C++) public Statement gccAsmSemantic(GccAsmStatement s, Scope *sc)
     // Analyse all clobbers.
     if (s.clobbers)
     {
-        foreach (i; 0 .. s.clobbers.dim)
+        foreach (i; 0 .. s.clobbers.length)
         {
             Expression e = (*s.clobbers)[i];
             e = e.expressionSemantic(sc);
@@ -365,7 +365,7 @@ extern (C++) public Statement gccAsmSemantic(GccAsmStatement s, Scope *sc)
     // Analyse all goto labels.
     if (s.labels)
     {
-        foreach (i; 0 .. s.labels.dim)
+        foreach (i; 0 .. s.labels.length)
         {
             Identifier ident = (*s.labels)[i];
             GotoStatement gs = new GotoStatement(s.loc, ident);
diff --git a/gcc/d/dmd/init.d b/gcc/d/dmd/init.d
index 523b5b820d7..f57b4e644a3 100644
--- a/gcc/d/dmd/init.d
+++ b/gcc/d/dmd/init.d
@@ -271,10 +271,10 @@ Initializer syntaxCopy(Initializer inx)
     static Initializer copyStruct(StructInitializer vi)
     {
         auto si = new StructInitializer(vi.loc);
-        assert(vi.field.dim == vi.value.dim);
-        si.field.setDim(vi.field.dim);
-        si.value.setDim(vi.value.dim);
-        foreach (const i; 0 .. vi.field.dim)
+        assert(vi.field.length == vi.value.length);
+        si.field.setDim(vi.field.length);
+        si.value.setDim(vi.value.length);
+        foreach (const i; 0 .. vi.field.length)
         {
             si.field[i] = vi.field[i];
             si.value[i] = vi.value[i].syntaxCopy();
@@ -285,10 +285,10 @@ Initializer syntaxCopy(Initializer inx)
     static Initializer copyArray(ArrayInitializer vi)
     {
         auto ai = new ArrayInitializer(vi.loc);
-        assert(vi.index.dim == vi.value.dim);
-        ai.index.setDim(vi.index.dim);
-        ai.value.setDim(vi.value.dim);
-        foreach (const i; 0 .. vi.value.dim)
+        assert(vi.index.length == vi.value.length);
+        ai.index.setDim(vi.index.length);
+        ai.value.setDim(vi.value.length);
+        foreach (const i; 0 .. vi.value.length)
         {
             ai.index[i] = vi.index[i] ? vi.index[i].syntaxCopy() : null;
             ai.value[i] = vi.value[i].syntaxCopy();
diff --git a/gcc/d/dmd/initsem.d b/gcc/d/dmd/initsem.d
index ef39f594d88..ecaa5e8f710 100644
--- a/gcc/d/dmd/initsem.d
+++ b/gcc/d/dmd/initsem.d
@@ -55,7 +55,7 @@ Expression toAssocArrayLiteral(ArrayInitializer ai)
     Expression e;
     //printf("ArrayInitializer::toAssocArrayInitializer()\n");
     //static int i; if (++i == 2) assert(0);
-    const dim = ai.value.dim;
+    const dim = ai.value.length;
     auto keys = new Expressions(dim);
     auto values = new Expressions(dim);
     for (size_t i = 0; i < dim; i++)
@@ -249,7 +249,7 @@ extern(C++) Initializer initializerSemantic(Initializer init, Scope* sc, ref Typ
             auto ie = new ExpInitializer(i.loc, sle);
             return ie.initializerSemantic(sc, t, needInterpret);
         }
-        else if ((t.ty == Tdelegate || t.isPtrToFunction()) && i.value.dim == 0)
+        else if ((t.ty == Tdelegate || t.isPtrToFunction()) && i.value.length == 0)
         {
             const tok = (t.ty == Tdelegate) ? TOK.delegate_ : TOK.function_;
             /* Rewrite as empty delegate literal { }
@@ -315,7 +315,7 @@ extern(C++) Initializer initializerSemantic(Initializer init, Scope* sc, ref Typ
         }
         i.type = t;
         length = 0;
-        for (size_t j = 0; j < i.index.dim; j++)
+        for (size_t j = 0; j < i.index.length; j++)
         {
             Expression idx = i.index[j];
             if (idx)
@@ -350,7 +350,7 @@ extern(C++) Initializer initializerSemantic(Initializer init, Scope* sc, ref Typ
                 TupleExp te = ei.exp.isTupleExp();
                 i.index.remove(j);
                 i.value.remove(j);
-                for (size_t k = 0; k < te.exps.dim; ++k)
+                for (size_t k = 0; k < te.exps.length; ++k)
                 {
                     Expression e = (*te.exps)[k];
                     i.index.insert(j + k, cast(Expression)null);
@@ -475,7 +475,7 @@ extern(C++) Initializer initializerSemantic(Initializer init, Scope* sc, ref Typ
         {
             return i; // Failed, suppress duplicate error messages
         }
-        if (i.exp.type.isTypeTuple() && i.exp.type.isTypeTuple().arguments.dim == 0)
+        if (i.exp.type.isTypeTuple() && i.exp.type.isTypeTuple().arguments.length == 0)
         {
             Type et = i.exp.type;
             i.exp = new TupleExp(i.exp.loc, new Expressions());
@@ -638,7 +638,7 @@ extern(C++) Initializer initializerSemantic(Initializer init, Scope* sc, ref Typ
                 uinteger_t dim2 = dim1;
                 if (auto ale = i.exp.isArrayLiteralExp())
                 {
-                    dim2 = ale.elements ? ale.elements.dim : 0;
+                    dim2 = ale.elements ? ale.elements.length : 0;
                 }
                 else if (auto se = i.exp.isSliceExp())
                 {
@@ -1094,9 +1094,9 @@ Initializer inferType(Initializer init, Scope* sc)
         Expressions* values;
         if (init.isAssociativeArray())
         {
-            keys = new Expressions(init.value.dim);
-            values = new Expressions(init.value.dim);
-            for (size_t i = 0; i < init.value.dim; i++)
+            keys = new Expressions(init.value.length);
+            values = new Expressions(init.value.length);
+            for (size_t i = 0; i < init.value.length; i++)
             {
                 Expression e = init.index[i];
                 if (!e)
@@ -1119,9 +1119,9 @@ Initializer inferType(Initializer init, Scope* sc)
         }
         else
         {
-            auto elements = new Expressions(init.value.dim);
+            auto elements = new Expressions(init.value.length);
             elements.zero();
-            for (size_t i = 0; i < init.value.dim; i++)
+            for (size_t i = 0; i < init.value.length; i++)
             {
                 assert(!init.index[i]); // already asserted by isAssociativeArray()
                 Initializer iz = init.value[i];
@@ -1300,9 +1300,9 @@ extern (C++) Expression initializerToExpression(Initializer init, Type itype = n
         {
             /* Calculate the length of the array literal
              */
-            edim = cast(uint)init.value.dim;
+            edim = cast(uint)init.value.length;
             size_t j = 0;
-            foreach (i; 0 .. init.value.dim)
+            foreach (i; 0 .. init.value.length)
             {
                 if (auto e = init.index[i])
                 {
@@ -1325,7 +1325,7 @@ extern (C++) Expression initializerToExpression(Initializer init, Type itype = n
         auto elements = new Expressions(edim);
         elements.zero();
         size_t j = 0;
-        foreach (i; 0 .. init.value.dim)
+        foreach (i; 0 .. init.value.length)
         {
             if (auto e = init.index[i])
                 j = cast(size_t)e.toInteger();
diff --git a/gcc/d/dmd/json.d b/gcc/d/dmd/json.d
index a22c664f920..b7719d8439f 100644
--- a/gcc/d/dmd/json.d
+++ b/gcc/d/dmd/json.d
@@ -386,13 +386,13 @@ public:
 
     extern(D) void property(const char[] name, Parameters* parameters)
     {
-        if (parameters is null || parameters.dim == 0)
+        if (parameters is null || parameters.length == 0)
             return;
         propertyStart(name);
         arrayStart();
         if (parameters)
         {
-            for (size_t i = 0; i < parameters.dim; i++)
+            for (size_t i = 0; i < parameters.length; i++)
             {
                 Parameter p = (*parameters)[i];
                 objectStart();
@@ -491,7 +491,7 @@ public:
         property("comment", s.comment.toDString);
         propertyStart("members");
         arrayStart();
-        for (size_t i = 0; i < s.members.dim; i++)
+        for (size_t i = 0; i < s.members.length; i++)
         {
             (*s.members)[i].accept(this);
         }
@@ -522,7 +522,7 @@ public:
             property("alias", s.aliasId.toString());
         bool hasRenamed = false;
         bool hasSelective = false;
-        for (size_t i = 0; i < s.aliases.dim; i++)
+        for (size_t i = 0; i < s.aliases.length; i++)
         {
             // avoid empty "renamed" and "selective" sections
             if (hasRenamed && hasSelective)
@@ -537,7 +537,7 @@ public:
             // import foo : alias1 = target1;
             propertyStart("renamed");
             objectStart();
-            for (size_t i = 0; i < s.aliases.dim; i++)
+            for (size_t i = 0; i < s.aliases.length; i++)
             {
                 const name = s.names[i];
                 const _alias = s.aliases[i];
@@ -566,7 +566,7 @@ public:
         Dsymbols* ds = d.include(null);
         if (ds)
         {
-            for (size_t i = 0; i < ds.dim; i++)
+            for (size_t i = 0; i < ds.length; i++)
             {
                 Dsymbol s = (*ds)[i];
                 s.accept(this);
@@ -582,7 +582,7 @@ public:
             return; // Don't visit the if/else bodies again below
         }
         Dsymbols* ds = d.decl ? d.decl : d.elsedecl;
-        for (size_t i = 0; i < ds.dim; i++)
+        for (size_t i = 0; i < ds.length; i++)
         {
             Dsymbol s = (*ds)[i];
             s.accept(this);
@@ -631,7 +631,7 @@ public:
         {
             propertyStart("members");
             arrayStart();
-            for (size_t i = 0; i < d.members.dim; i++)
+            for (size_t i = 0; i < d.members.length; i++)
             {
                 Dsymbol s = (*d.members)[i];
                 s.accept(this);
@@ -649,11 +649,11 @@ public:
         if (tf && tf.ty == Tfunction)
             property("parameters", tf.parameterList.parameters);
         property("endline", "endchar", d.endloc);
-        if (d.foverrides.dim)
+        if (d.foverrides.length)
         {
             propertyStart("overrides");
             arrayStart();
-            for (size_t i = 0; i < d.foverrides.dim; i++)
+            for (size_t i = 0; i < d.foverrides.length; i++)
             {
                 FuncDeclaration fd = d.foverrides[i];
                 item(fd.toPrettyChars().toDString);
@@ -681,7 +681,7 @@ public:
         jsonProperties(d);
         propertyStart("parameters");
         arrayStart();
-        for (size_t i = 0; i < d.parameters.dim; i++)
+        for (size_t i = 0; i < d.parameters.length; i++)
         {
             TemplateParameter s = (*d.parameters)[i];
             objectStart();
@@ -732,7 +732,7 @@ public:
         }
         propertyStart("members");
         arrayStart();
-        for (size_t i = 0; i < d.members.dim; i++)
+        for (size_t i = 0; i < d.members.length; i++)
         {
             Dsymbol s = (*d.members)[i];
             s.accept(this);
@@ -747,7 +747,7 @@ public:
         {
             if (d.members)
             {
-                for (size_t i = 0; i < d.members.dim; i++)
+                for (size_t i = 0; i < d.members.length; i++)
                 {
                     Dsymbol s = (*d.members)[i];
                     s.accept(this);
@@ -762,7 +762,7 @@ public:
         {
             propertyStart("members");
             arrayStart();
-            for (size_t i = 0; i < d.members.dim; i++)
+            for (size_t i = 0; i < d.members.length; i++)
             {
                 Dsymbol s = (*d.members)[i];
                 s.accept(this);
@@ -963,7 +963,7 @@ public:
             requiredProperty("name", m.md ? m.md.toString() : null);
             requiredProperty("file", m.srcfile.toString());
             propertyBool("isRoot", m.isRoot());
-            if(m.contentImportedFiles.dim > 0)
+            if(m.contentImportedFiles.length > 0)
             {
                 propertyStart("contentImports");
                 arrayStart();
diff --git a/gcc/d/dmd/lambdacomp.d b/gcc/d/dmd/lambdacomp.d
index 91df9cc9f25..e1ed717ab85 100644
--- a/gcc/d/dmd/lambdacomp.d
+++ b/gcc/d/dmd/lambdacomp.d
@@ -452,7 +452,7 @@ public:
         if (ty)
         {
             writeMangledName(ty.sym);
-            auto dim = e.elements.dim;
+            auto dim = e.elements.length;
             foreach (i; 0..dim)
             {
                 auto elem = (*e.elements)[i];
diff --git a/gcc/d/dmd/lexer.d b/gcc/d/dmd/lexer.d
index 451e227e98a..200d74f3aad 100644
--- a/gcc/d/dmd/lexer.d
+++ b/gcc/d/dmd/lexer.d
@@ -126,18 +126,26 @@ class Lexer
         if (p && p[0] == '#' && p[1] == '!')
         {
             p += 2;
-            while (1)
+            for (;;p++)
             {
-                char c = *p++;
+                char c = *p;
                 switch (c)
                 {
+                case '\n':
+                    p++;
+                    goto case;
                 case 0:
                 case 0x1A:
-                    p--;
-                    goto case;
-                case '\n':
                     break;
+
                 default:
+                    // Note: We do allow malformed UTF-8 on shebang line.
+                    // It could have a meaning if the native system
+                    // encoding is not Unicode. See test compilable/test13512.d
+                    // for example encoded in KOI-8.
+                    // We also allow bidirectional control characters.
+                    // We do not execute the shebang line, so it can't be used
+                    // to conceal code. It is up to the shell to sanitize it.
                     continue;
                 }
                 break;
@@ -522,7 +530,7 @@ class Lexer
                             const u = decodeUTF();
                             if (isUniAlpha(u))
                                 continue;
-                            error("char 0x%04x not allowed in identifier", u);
+                            error(t.loc, "char 0x%04x not allowed in identifier", u);
                             p = s;
                         }
                         break;
@@ -620,7 +628,7 @@ class Lexer
                                 continue;
                             case 0:
                             case 0x1A:
-                                error("unterminated /* */ comment");
+                                error(t.loc, "unterminated /* */ comment");
                                 p = end;
                                 t.loc = loc();
                                 t.value = TOK.endOfFile;
@@ -756,7 +764,7 @@ class Lexer
                                 continue;
                             case 0:
                             case 0x1A:
-                                error("unterminated /+ +/ comment");
+                                error(t.loc, "unterminated /+ +/ comment");
                                 p = end;
                                 t.loc = loc();
                                 t.value = TOK.endOfFile;
@@ -1126,11 +1134,12 @@ class Lexer
                         }
                     }
                     if (c < 0x80 && isprint(c))
-                        error("character '%c' is not a valid token", c);
+                        error(t.loc, "character '%c' is not a valid token", c);
                     else
-                        error("character 0x%02x is not a valid token", c);
+                        error(t.loc, "character 0x%02x is not a valid token", c);
                     p++;
                     continue;
+                    // assert(0);
                 }
             }
         }
@@ -1467,6 +1476,7 @@ class Lexer
         stringbuffer.setsize(0);
         while (1)
         {
+            const s = p;
             dchar c = *p++;
             //printf("c = '%c'\n", c);
             switch (c)
@@ -1526,7 +1536,7 @@ class Lexer
                 {
                     // Start of identifier; must be a heredoc
                     Token tok;
-                    p--;
+                    p = s;
                     scan(&tok); // read in heredoc identifier
                     if (tok.value != TOK.identifier)
                     {
@@ -1574,7 +1584,7 @@ class Lexer
                 {
                     Token tok;
                     auto psave = p;
-                    p--;
+                    p = s;
                     scan(&tok); // read in possible heredoc identifier
                     //printf("endid = '%s'\n", tok.ident.toChars());
                     if (tok.value == TOK.identifier && tok.ident is hereid)
@@ -2829,6 +2839,20 @@ class Lexer
      * Return decoded character, advance p to last character in UTF sequence.
      */
     private uint decodeUTF()
+    {
+        string msg;
+        auto result = decodeUTFpure(msg);
+
+        if (msg)
+            error("%.*s", cast(int)msg.length, msg.ptr);
+        return result;
+    }
+
+    /********************************************
+     * Same as above, but the potential error message is stored to the
+     * msg parameter instead of being issued.
+     */
+    private pure uint decodeUTFpure(out string msg)
     {
         const s = p;
         assert(*s & 0x80);
@@ -2839,12 +2863,10 @@ class Lexer
         }
         size_t idx = 0;
         dchar u;
-        const msg = utf_decodeChar(s[0 .. len], idx, u);
+        msg = utf_decodeChar(s[0 .. len], idx, u);
         p += idx - 1;
-        if (msg)
-        {
-            error("%.*s", cast(int)msg.length, msg.ptr);
-        }
+        if (!msg && isBidiControl(u))
+            msg = "Bidirectional control characters are disallowed for security reasons.";
         return u;
     }
 
diff --git a/gcc/d/dmd/mtype.d b/gcc/d/dmd/mtype.d
index 265f731cedd..2c0a5718421 100644
--- a/gcc/d/dmd/mtype.d
+++ b/gcc/d/dmd/mtype.d
@@ -4556,7 +4556,7 @@ extern (C++) final class TypeFunction : TypeNext
         Parameters* params = parameterList.parameters;
         if (mod & MODFlags.wild)
             params = parameterList.parameters.copy();
-        for (size_t i = 0; i < params.dim; i++)
+        for (size_t i = 0; i < params.length; i++)
         {
             Parameter p = (*params)[i];
             Type t = p.type.substWildTo(m);
@@ -4686,7 +4686,7 @@ extern (C++) final class TypeFunction : TypeNext
         if (parameterList.varargs == VarArg.none && nparams > nargs && !parameterList[nargs].defaultArg)
         {
             OutBuffer buf;
-            buf.printf("too few arguments, expected `%d`, got `%d`", cast(int)nparams, cast(int)nargs);
+            buf.printf("too few arguments, expected %d, got %d", cast(int)nparams, cast(int)nargs);
             if (pMessage)
                 *pMessage = buf.extractChars();
             return MATCH.nomatch;
@@ -5108,8 +5108,8 @@ extern (C++) abstract class TypeQualified : Type
     final void syntaxCopyHelper(TypeQualified t)
     {
         //printf("TypeQualified::syntaxCopyHelper(%s) %s\n", t.toChars(), toChars());
-        idents.setDim(t.idents.dim);
-        for (size_t i = 0; i < idents.dim; i++)
+        idents.setDim(t.idents.length);
+        for (size_t i = 0; i < idents.length; i++)
         {
             RootObject id = t.idents[i];
             with (DYNCAST) final switch (id.dyncast())
@@ -5251,7 +5251,7 @@ extern (C++) final class TypeInstance : TypeQualified
 
     override TypeInstance syntaxCopy()
     {
-        //printf("TypeInstance::syntaxCopy() %s, %d\n", toChars(), idents.dim);
+        //printf("TypeInstance::syntaxCopy() %s, %d\n", toChars(), idents.length);
         auto t = new TypeInstance(loc, tempinst.syntaxCopy(null));
         t.syntaxCopyHelper(this);
         t.mod = mod;
@@ -5432,7 +5432,7 @@ extern (C++) final class TypeStruct : Type
 
         auto structelems = new Expressions(sym.nonHiddenFields());
         uint offset = 0;
-        foreach (j; 0 .. structelems.dim)
+        foreach (j; 0 .. structelems.length)
         {
             VarDeclaration vd = sym.fields[j];
             Expression e;
@@ -5487,7 +5487,7 @@ extern (C++) final class TypeStruct : Type
         /* If any of the fields are const or immutable,
          * then one cannot assign this struct.
          */
-        for (size_t i = 0; i < sym.fields.dim; i++)
+        for (size_t i = 0; i < sym.fields.length; i++)
         {
             VarDeclaration v = sym.fields[i];
             //printf("%s [%d] v = (%s) %s, v.offset = %d, v.parent = %s\n", sym.toChars(), i, v.kind(), v.toChars(), v.offset, v.parent.kind());
@@ -5541,7 +5541,7 @@ extern (C++) final class TypeStruct : Type
         if (sym.isNested())
             return true;
 
-        for (size_t i = 0; i < sym.fields.dim; i++)
+        for (size_t i = 0; i < sym.fields.length; i++)
         {
             VarDeclaration v = sym.fields[i];
             if (!v.isDataseg() && v.type.needsNested())
@@ -5599,7 +5599,7 @@ extern (C++) final class TypeStruct : Type
                      * allow the conversion.
                      */
                     uint offset = ~0; // dead-store to prevent spurious warning
-                    for (size_t i = 0; i < sym.fields.dim; i++)
+                    for (size_t i = 0; i < sym.fields.length; i++)
                     {
                         VarDeclaration v = sym.fields[i];
                         if (i == 0)
@@ -6072,7 +6072,7 @@ extern (C++) final class TypeTuple : Type
         {
             if (arguments)
             {
-                for (size_t i = 0; i < arguments.dim; i++)
+                for (size_t i = 0; i < arguments.length; i++)
                 {
                     Parameter arg = (*arguments)[i];
                     assert(arg && arg.type);
@@ -6088,10 +6088,10 @@ extern (C++) final class TypeTuple : Type
     extern (D) this(Expressions* exps)
     {
         super(Ttuple);
-        auto arguments = new Parameters(exps ? exps.dim : 0);
+        auto arguments = new Parameters(exps ? exps.length : 0);
         if (exps)
         {
-            for (size_t i = 0; i < exps.dim; i++)
+            for (size_t i = 0; i < exps.length; i++)
             {
                 Expression e = (*exps)[i];
                 if (e.type.ty == Ttuple)
@@ -6169,9 +6169,9 @@ extern (C++) final class TypeTuple : Type
             return true;
         if (auto tt = t.isTypeTuple())
         {
-            if (arguments.dim == tt.arguments.dim)
+            if (arguments.length == tt.arguments.length)
             {
-                for (size_t i = 0; i < tt.arguments.dim; i++)
+                for (size_t i = 0; i < tt.arguments.length; i++)
                 {
                     const Parameter arg1 = (*arguments)[i];
                     Parameter arg2 = (*tt.arguments)[i];
@@ -6190,10 +6190,10 @@ extern (C++) final class TypeTuple : Type
             return MATCH.exact;
         if (auto tt = to.isTypeTuple())
         {
-            if (arguments.dim == tt.arguments.dim)
+            if (arguments.length == tt.arguments.length)
             {
                 MATCH m = MATCH.exact;
-                for (size_t i = 0; i < tt.arguments.dim; i++)
+                for (size_t i = 0; i < tt.arguments.length; i++)
                 {
                     Parameter arg1 = (*arguments)[i];
                     Parameter arg2 = (*tt.arguments)[i];
@@ -6595,8 +6595,8 @@ extern (C++) final class Parameter : ASTNode
         Parameters* params = null;
         if (parameters)
         {
-            params = new Parameters(parameters.dim);
-            for (size_t i = 0; i < params.dim; i++)
+            params = new Parameters(parameters.length);
+            for (size_t i = 0; i < params.length; i++)
                 (*params)[i] = (*parameters)[i].syntaxCopy();
         }
         return params;
diff --git a/gcc/d/dmd/nogc.d b/gcc/d/dmd/nogc.d
index 7ddeeecae9b..3329c14afbf 100644
--- a/gcc/d/dmd/nogc.d
+++ b/gcc/d/dmd/nogc.d
@@ -99,7 +99,7 @@ public:
 
     override void visit(ArrayLiteralExp e)
     {
-        if (e.type.ty != Tarray || !e.elements || !e.elements.dim || e.onstack)
+        if (e.type.ty != Tarray || !e.elements || !e.elements.length || e.onstack)
             return;
         if (f.setGC())
         {
@@ -113,7 +113,7 @@ public:
 
     override void visit(AssocArrayLiteralExp e)
     {
-        if (!e.keys.dim)
+        if (!e.keys.length)
             return;
         if (f.setGC())
         {
@@ -162,16 +162,16 @@ public:
     override void visit(IndexExp e)
     {
         Type t1b = e.e1.type.toBasetype();
-        if (t1b.ty == Taarray)
+        if (e.modifiable && t1b.ty == Taarray)
         {
             if (f.setGC())
             {
-                e.error("indexing an associative array in `@nogc` %s `%s` may cause a GC allocation",
+                e.error("assigning an associative array element in `@nogc` %s `%s` may cause a GC allocation",
                     f.kind(), f.toPrettyChars());
                 err = true;
                 return;
             }
-            f.printGCUsage(e.loc, "indexing an associative array may cause a GC allocation");
+            f.printGCUsage(e.loc, "assigning an associative array element may cause a GC allocation");
         }
     }
 
diff --git a/gcc/d/dmd/ob.d b/gcc/d/dmd/ob.d
index 5ff73c983f0..59f34e1c1de 100644
--- a/gcc/d/dmd/ob.d
+++ b/gcc/d/dmd/ob.d
@@ -565,7 +565,7 @@ void toObNodes(ref ObNodes obnodes, Statement s)
              */
             mystate.defaultBlock = s.sdefault ? newNode() : mystate.breakBlock;
 
-            const numcases = s.cases ? s.cases.dim : 0;
+            const numcases = s.cases ? s.cases.length : 0;
 
             /* allocate a block for each case
              */
diff --git a/gcc/d/dmd/objc.d b/gcc/d/dmd/objc.d
index 9afedc1c27b..2bb5eabe4eb 100644
--- a/gcc/d/dmd/objc.d
+++ b/gcc/d/dmd/objc.d
@@ -555,7 +555,7 @@ extern(C++) private final class Supported : Objc
                 return 1;
             }
 
-            assert(literal.elements.dim == 1);
+            assert(literal.elements.length == 1);
             auto se = (*literal.elements)[0].toStringExp();
             assert(se);
 
@@ -570,7 +570,7 @@ extern(C++) private final class Supported : Objc
         if (!fd.objc.selector)
             return;
         TypeFunction tf = cast(TypeFunction)fd.type;
-        if (fd.objc.selector.paramCount != tf.parameterList.parameters.dim)
+        if (fd.objc.selector.paramCount != tf.parameterList.parameters.length)
             fd.error("number of colons in Objective-C selector must match number of parameters");
         if (fd.parent && fd.parent.isTemplateInstance())
             fd.error("template cannot have an Objective-C selector attached");
diff --git a/gcc/d/dmd/opover.d b/gcc/d/dmd/opover.d
index ca99b8bdc36..de417274a66 100644
--- a/gcc/d/dmd/opover.d
+++ b/gcc/d/dmd/opover.d
@@ -286,9 +286,9 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null)
                 ae.e1 = ae.e1.expressionSemantic(sc);
                 ae.e1 = resolveProperties(sc, ae.e1);
                 Expression ae1old = ae.e1;
-                const(bool) maybeSlice = (ae.arguments.dim == 0 || ae.arguments.dim == 1 && (*ae.arguments)[0].op == EXP.interval);
+                const(bool) maybeSlice = (ae.arguments.length == 0 || ae.arguments.length == 1 && (*ae.arguments)[0].op == EXP.interval);
                 IntervalExp ie = null;
-                if (maybeSlice && ae.arguments.dim)
+                if (maybeSlice && ae.arguments.length)
                 {
                     ie = (*ae.arguments)[0].isIntervalExp();
                 }
@@ -425,9 +425,9 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null)
             ae.e1 = ae.e1.expressionSemantic(sc);
             ae.e1 = resolveProperties(sc, ae.e1);
             Expression ae1old = ae.e1;
-            const(bool) maybeSlice = (ae.arguments.dim == 0 || ae.arguments.dim == 1 && (*ae.arguments)[0].op == EXP.interval);
+            const(bool) maybeSlice = (ae.arguments.length == 0 || ae.arguments.length == 1 && (*ae.arguments)[0].op == EXP.interval);
             IntervalExp ie = null;
-            if (maybeSlice && ae.arguments.dim)
+            if (maybeSlice && ae.arguments.length)
             {
                 ie = (*ae.arguments)[0].isIntervalExp();
             }
@@ -457,7 +457,7 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null)
                             return result;
                         }
                         // Convert to IndexExp
-                        if (ae.arguments.dim == 1)
+                        if (ae.arguments.length == 1)
                         {
                             result = new IndexExp(ae.loc, ae.e1, (*ae.arguments)[0]);
                             result = result.expressionSemantic(sc);
@@ -849,7 +849,7 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null)
                      * the mentioned member, then alias this may be
                      * used since the object will be fully initialised.
                      * If the struct is nested, the context pointer is considered
-                     * one of the members, hence the `ad1.fields.dim == 2 && ad1.vthis`
+                     * one of the members, hence the `ad1.fields.length == 2 && ad1.vthis`
                      * condition.
                      */
                     if (result.op != EXP.assign)
@@ -864,7 +864,7 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null)
                     {
                         // i.e: Rewrote `e1 = e2` -> `e1.some.var = e2`
                         // Ensure that `var` is the only field member in `ad`
-                        if (ad.fields.dim == 1 || (ad.fields.dim == 2 && ad.vthis))
+                        if (ad.fields.length == 1 || (ad.fields.length == 2 && ad.vthis))
                         {
                             if (dve.var == ad.aliasthis.sym)
                                 return result;
@@ -1043,11 +1043,11 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null)
             {
                 auto tup1 = e.e1.isTupleExp();
                 auto tup2 = e.e2.isTupleExp();
-                size_t dim = tup1.exps.dim;
-                if (dim != tup2.exps.dim)
+                size_t dim = tup1.exps.length;
+                if (dim != tup2.exps.length)
                 {
                     e.error("mismatched tuple lengths, `%d` and `%d`",
-                        cast(int)dim, cast(int)tup2.exps.dim);
+                        cast(int)dim, cast(int)tup2.exps.length);
                     return ErrorExp.get();
                 }
 
@@ -1101,9 +1101,9 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null)
                 ae.e1 = ae.e1.expressionSemantic(sc);
                 ae.e1 = resolveProperties(sc, ae.e1);
                 Expression ae1old = ae.e1;
-                const(bool) maybeSlice = (ae.arguments.dim == 0 || ae.arguments.dim == 1 && (*ae.arguments)[0].op == EXP.interval);
+                const(bool) maybeSlice = (ae.arguments.length == 0 || ae.arguments.length == 1 && (*ae.arguments)[0].op == EXP.interval);
                 IntervalExp ie = null;
-                if (maybeSlice && ae.arguments.dim)
+                if (maybeSlice && ae.arguments.length)
                 {
                     ie = (*ae.arguments)[0].isIntervalExp();
                 }
@@ -1553,7 +1553,7 @@ bool inferForeachAggregate(Scope* sc, bool isForeach, ref Expression feaggr, out
  */
 bool inferApplyArgTypes(ForeachStatement fes, Scope* sc, ref Dsymbol sapply)
 {
-    if (!fes.parameters || !fes.parameters.dim)
+    if (!fes.parameters || !fes.parameters.length)
         return false;
     if (sapply) // prefer opApply
     {
@@ -1604,7 +1604,7 @@ bool inferApplyArgTypes(ForeachStatement fes, Scope* sc, ref Dsymbol sapply)
     case Tarray:
     case Tsarray:
     case Ttuple:
-        if (fes.parameters.dim == 2)
+        if (fes.parameters.length == 2)
         {
             if (!p.type)
             {
@@ -1623,7 +1623,7 @@ bool inferApplyArgTypes(ForeachStatement fes, Scope* sc, ref Dsymbol sapply)
     case Taarray:
         {
             TypeAArray taa = tab.isTypeAArray();
-            if (fes.parameters.dim == 2)
+            if (fes.parameters.length == 2)
             {
                 if (!p.type)
                 {
@@ -1647,7 +1647,7 @@ bool inferApplyArgTypes(ForeachStatement fes, Scope* sc, ref Dsymbol sapply)
     {
         AggregateDeclaration ad = (tab.ty == Tclass) ? tab.isTypeClass().sym
                                                      : tab.isTypeStruct().sym;
-        if (fes.parameters.dim == 1)
+        if (fes.parameters.length == 1)
         {
             if (!p.type)
             {
@@ -1811,7 +1811,7 @@ private bool matchParamsToOpApply(TypeFunction tf, Parameters* parameters, bool
      * Fill in missing types in parameters.
      */
     const nparams = tdg.parameterList.length;
-    if (nparams == 0 || nparams != parameters.dim || tdg.parameterList.varargs != VarArg.none)
+    if (nparams == 0 || nparams != parameters.length || tdg.parameterList.varargs != VarArg.none)
         return nomatch; // parameter mismatch
 
     foreach (u, p; *parameters)
diff --git a/gcc/d/dmd/optimize.d b/gcc/d/dmd/optimize.d
index be28d082405..a9c542579ad 100644
--- a/gcc/d/dmd/optimize.d
+++ b/gcc/d/dmd/optimize.d
@@ -225,7 +225,7 @@ package void setLengthVarIfKnown(VarDeclaration lengthVar, Expression arr)
     if (auto se = arr.isStringExp())
         len = se.len;
     else if (auto ale = arr.isArrayLiteralExp())
-        len = ale.elements.dim;
+        len = ale.elements.length;
     else
     {
         auto tsa = arr.type.toBasetype().isTypeSArray();
@@ -358,7 +358,7 @@ Expression Expression_optimize(Expression e, int result, bool keepLvalue)
 
     void visitAssocArrayLiteral(AssocArrayLiteralExp e)
     {
-        assert(e.keys.dim == e.values.dim);
+        assert(e.keys.length == e.values.length);
         foreach (i, ref ekey; (*e.keys)[])
         {
             expOptimize(ekey, result & WANTexpand);
diff --git a/gcc/d/dmd/parse.d b/gcc/d/dmd/parse.d
index 6fb542fb9aa..93c7ea0eea0 100644
--- a/gcc/d/dmd/parse.d
+++ b/gcc/d/dmd/parse.d
@@ -425,8 +425,8 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
             case TOK.traits:
             Ldeclaration:
                 a = parseDeclarations(false, pAttrs, pAttrs.comment);
-                if (a && a.dim)
-                    *pLastDecl = (*a)[a.dim - 1];
+                if (a && a.length)
+                    *pLastDecl = (*a)[a.length - 1];
                 break;
 
             case TOK.this_:
@@ -491,6 +491,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
                  */
                 if (mod.isRoot() && (global.params.useUnitTests || global.params.ddoc.doOutput || global.params.dihdr.doOutput))
                 {
+                    linkage = LINK.d; // unittests have D linkage
                     s = parseUnitTest(pAttrs);
                     if (*pLastDecl)
                         (*pLastDecl).ddocUnittest = cast(AST.UnitTestDeclaration)s;
@@ -698,8 +699,8 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
                 if (token.value == TOK.identifier && hasOptionalParensThen(peek(&token), TOK.assign))
                 {
                     a = parseAutoDeclarations(getStorageClass!AST(pAttrs), pAttrs.comment);
-                    if (a && a.dim)
-                        *pLastDecl = (*a)[a.dim - 1];
+                    if (a && a.length)
+                        *pLastDecl = (*a)[a.length - 1];
                     if (pAttrs.udas)
                     {
                         s = new AST.UserAttributeDeclaration(pAttrs.udas, a);
@@ -725,8 +726,8 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
                         deprecation("usage of the `body` keyword is deprecated. Use `do` instead.");
 
                     a = parseDeclarations(true, pAttrs, pAttrs.comment);
-                    if (a && a.dim)
-                        *pLastDecl = (*a)[a.dim - 1];
+                    if (a && a.length)
+                        *pLastDecl = (*a)[a.length - 1];
                     if (pAttrs.udas)
                     {
                         s = new AST.UserAttributeDeclaration(pAttrs.udas, a);
@@ -817,8 +818,8 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
                     if (res.idents)
                     {
                         assert(res.link == LINK.cpp);
-                        assert(res.idents.dim);
-                        for (size_t i = res.idents.dim; i;)
+                        assert(res.idents.length);
+                        for (size_t i = res.idents.length; i;)
                         {
                             Identifier id = (*res.idents)[--i];
                             if (s)
@@ -833,8 +834,8 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
                     else if (res.identExps)
                     {
                         assert(res.link == LINK.cpp);
-                        assert(res.identExps.dim);
-                        for (size_t i = res.identExps.dim; i;)
+                        assert(res.identExps.length);
+                        for (size_t i = res.identExps.length; i;)
                         {
                             AST.Expression exp = (*res.identExps)[--i];
                             if (s)
@@ -1059,7 +1060,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
                 decldefs.push(s);
                 addComment(s, pAttrs.comment);
             }
-            else if (a && a.dim)
+            else if (a && a.length)
             {
                 decldefs.append(a);
             }
@@ -3786,10 +3787,10 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
                                 break;
                             }
                         }
-                        assert(dimStack.dim > 0);
+                        assert(dimStack.length > 0);
                         // We're good. Replay indices in the reverse order.
                         tid = cast(AST.TypeQualified)t;
-                        while (dimStack.dim)
+                        while (dimStack.length)
                         {
                             tid.addIndex(dimStack.pop());
                         }
@@ -4341,6 +4342,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
         /* Declarations that start with `alias`
          */
         bool isAliasDeclaration = false;
+        auto aliasLoc = token.loc;
         if (token.value == TOK.alias_)
         {
             if (auto a = parseAliasDeclarations(comment))
@@ -4488,7 +4490,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
             if (ident)
                 checkCstyleTypeSyntax(loc, t, alt, ident);
             else if (!isThis && (t != AST.Type.terror))
-                error("no identifier for declarator `%s`", t.toChars());
+                noIdentifierForDeclarator(t);
 
             if (isAliasDeclaration)
             {
@@ -4517,7 +4519,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
                     else
                         error("alias cannot have initializer");
                 }
-                v = new AST.AliasDeclaration(loc, ident, t);
+                v = new AST.AliasDeclaration(aliasLoc, ident, t);
 
                 v.storage_class = storage_class;
                 if (pAttrs)
@@ -4706,6 +4708,19 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
         return a;
     }
 
+    /// Report an error that a declaration of type `t` is missing an identifier
+    /// The parser is expected to sit on the next token after the type.
+    private void noIdentifierForDeclarator(AST.Type t)
+    {
+        error("no identifier for declarator `%s`", t.toChars());
+        // A common mistake is to use a reserved keyword as an identifier, e.g. `in` or `out`
+        if (token.isKeyword)
+        {
+            errorSupplemental(token.loc, "`%s` is a keyword, perhaps append `_` to make it an identifier", token.toChars());
+            nextToken();
+        }
+    }
+
     /********************************
      * Parse AliasReassignment:
      *   identifier = type;
@@ -4881,7 +4896,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
                         // parseAttributes shouldn't have set these variables
                         assert(link == linkage && !setAlignment && ealign is null);
                         auto tpl_ = cast(AST.TemplateDeclaration) s;
-                        if (tpl_ is null || tpl_.members.dim != 1)
+                        if (tpl_ is null || tpl_.members.length != 1)
                         {
                             error("user-defined attributes are not allowed on `alias` declarations");
                         }
@@ -4889,7 +4904,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
                         {
                             auto fd = cast(AST.FuncLiteralDeclaration) (*tpl_.members)[0];
                             auto tf = cast(AST.TypeFunction) fd.type;
-                            assert(tf.parameterList.parameters.dim > 0);
+                            assert(tf.parameterList.parameters.length > 0);
                             auto as = new AST.Dsymbols();
                             (*tf.parameterList.parameters)[0].userAttribDecl = new AST.UserAttributeDeclaration(udas, as);
                         }
@@ -5489,7 +5504,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
             }
             at = parseType(&ai);
             if (!ai)
-                error("no identifier for declarator `%s`", at.toChars());
+                noIdentifierForDeclarator(at);
         Larg:
             auto p = new AST.Parameter(storageClass, at, ai, null, null);
             parameters.push(p);
@@ -5513,7 +5528,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
         nextToken();
 
         AST.Expression aggr = parseExpression();
-        if (token.value == TOK.slice && parameters.dim == 1)
+        if (token.value == TOK.slice && parameters.length == 1)
         {
             AST.Parameter p = (*parameters)[0];
             nextToken();
@@ -5897,11 +5912,11 @@ LagainStc:
         Ldeclaration:
             {
                 AST.Dsymbols* a = parseDeclarations(false, null, null);
-                if (a.dim > 1)
+                if (a.length > 1)
                 {
                     auto as = new AST.Statements();
-                    as.reserve(a.dim);
-                    foreach (i; 0 .. a.dim)
+                    as.reserve(a.length);
+                    foreach (i; 0 .. a.length)
                     {
                         AST.Dsymbol d = (*a)[i];
                         s = new AST.ExpStatement(loc, d);
@@ -5909,7 +5924,7 @@ LagainStc:
                     }
                     s = new AST.CompoundDeclarationStatement(loc, as);
                 }
-                else if (a.dim == 1)
+                else if (a.length == 1)
                 {
                     AST.Dsymbol d = (*a)[0];
                     s = new AST.ExpStatement(loc, d);
@@ -6283,7 +6298,7 @@ LagainStc:
                  */
                 if (token.value == TOK.slice)
                 {
-                    if (cases.dim > 1)
+                    if (cases.length > 1)
                         error("only one `case` allowed for start of case range");
                     nextToken();
                     check(TOK.case_);
@@ -6322,7 +6337,7 @@ LagainStc:
                 else
                 {
                     // Keep cases in order by building the case statements backwards
-                    for (size_t i = cases.dim; i; i--)
+                    for (size_t i = cases.length; i; i--)
                     {
                         exp = cases[i - 1];
                         s = new AST.CaseStatement(loc, exp, s);
@@ -6741,7 +6756,7 @@ LagainStc:
         case TOK.leftBracket:
             /* Scan ahead to see if it is an array initializer or
              * an expression.
-             * If it ends with a ';' ',' or '}', it is an array initializer.
+             * If it ends with a ';' ',' or ']', it is an array initializer.
              */
             int brackets = 1;
             for (auto t = peek(&token); 1; t = peek(t))
@@ -8242,6 +8257,13 @@ LagainStc:
             t = AST.Type.tdchar;
             goto LabelX;
         LabelX:
+            const next = peekNext();
+            if (next != TOK.leftParenthesis && next != TOK.dot)
+            {
+                // defer error for better diagnostics
+                e = new AST.TypeExp(loc, parseType);
+                break;
+            }
             nextToken();
             if (token.value == TOK.leftParenthesis)
             {
@@ -8249,7 +8271,7 @@ LagainStc:
                 e = new AST.CallExp(loc, e, parseArguments());
                 break;
             }
-            check(TOK.dot, t.toChars());
+            check(TOK.dot);
             if (token.value != TOK.identifier)
             {
                 error("found `%s` when expecting identifier following `%s`.", token.toChars(), t.toChars());
@@ -8477,7 +8499,7 @@ LagainStc:
                 while (token.value != TOK.rightBracket && token.value != TOK.endOfFile)
                 {
                     e = parseAssignExp();
-                    if (token.value == TOK.colon && (keys || values.dim == 0))
+                    if (token.value == TOK.colon && (keys || values.length == 0))
                     {
                         nextToken();
                         if (!keys)
diff --git a/gcc/d/dmd/root/array.d b/gcc/d/dmd/root/array.d
index 212fe96f4dc..5c01940dadb 100644
--- a/gcc/d/dmd/root/array.d
+++ b/gcc/d/dmd/root/array.d
@@ -352,7 +352,9 @@ public:
     }
 
     alias opDollar = length;
-    alias dim = length;
+
+    deprecated("use `.length` instead")
+    extern(D) size_t dim() const @nogc nothrow pure @safe { return length; }
 }
 
 unittest
diff --git a/gcc/d/dmd/root/filename.d b/gcc/d/dmd/root/filename.d
index 226141d4608..f6a451596bb 100644
--- a/gcc/d/dmd/root/filename.d
+++ b/gcc/d/dmd/root/filename.d
@@ -55,7 +55,7 @@ alias Strings = Array!(const(char)*);
 
 
 // Check whether character is a directory separator
-private bool isDirSeparator(char c) pure nothrow @nogc @safe
+bool isDirSeparator(char c) pure nothrow @nogc @safe
 {
     version (Windows)
     {
diff --git a/gcc/d/dmd/root/utf.d b/gcc/d/dmd/root/utf.d
index eb198fc7603..0d230e764c3 100644
--- a/gcc/d/dmd/root/utf.d
+++ b/gcc/d/dmd/root/utf.d
@@ -395,6 +395,26 @@ void utf_encode(int sz, void* s, dchar c)
     }
 }
 
+/********************************************
+ * Checks whether an Unicode code point is a bidirectional
+ * control character.
+ */
+@safe bool isBidiControl(dchar c)
+{
+    // Source: https://www.unicode.org/versions/Unicode15.0.0, table 23-3.
+    switch(c)
+    {
+        case '\u061C':
+        case '\u200E':
+        case '\u200F':
+        case '\u202A': .. case '\u202E':
+        case '\u2066': .. case '\u2069':
+            return true;
+        default:
+            return false;
+    }
+}
+
 /********************************************
  * Decode a UTF-8 sequence as a single UTF-32 code point.
  * Params:
diff --git a/gcc/d/dmd/sapply.d b/gcc/d/dmd/sapply.d
index 26fba8f3864..adfae329e06 100644
--- a/gcc/d/dmd/sapply.d
+++ b/gcc/d/dmd/sapply.d
@@ -68,7 +68,7 @@ public:
 
     override void visit(CompoundStatement s)
     {
-        for (size_t i = 0; i < s.statements.dim; i++)
+        for (size_t i = 0; i < s.statements.length; i++)
             if (doCond((*s.statements)[i]))
                 return;
         applyTo(s);
@@ -76,7 +76,7 @@ public:
 
     override void visit(UnrolledLoopStatement s)
     {
-        for (size_t i = 0; i < s.statements.dim; i++)
+        for (size_t i = 0; i < s.statements.length; i++)
             if (doCond((*s.statements)[i]))
                 return;
         applyTo(s);
@@ -151,7 +151,7 @@ public:
     {
         if (doCond(s._body))
             return;
-        for (size_t i = 0; i < s.catches.dim; i++)
+        for (size_t i = 0; i < s.catches.length; i++)
             if (doCond((*s.catches)[i].handler))
                 return;
         applyTo(s);
diff --git a/gcc/d/dmd/scope.h b/gcc/d/dmd/scope.h
index b29c59943f3..8b9e59e3aae 100644
--- a/gcc/d/dmd/scope.h
+++ b/gcc/d/dmd/scope.h
@@ -28,43 +28,38 @@ class CPPNamespaceDeclaration;
 
 #include "dsymbol.h"
 
-enum
+enum class CSX : uint16_t
 {
-    CSXthis_ctor  = 1,      // called this()
-    CSXsuper_ctor = 2,      // called super()
-    CSXthis       = 4,      // referenced this
-    CSXsuper      = 8,      // referenced super
-    CSXlabel      = 0x10,   // seen a label
-    CSXreturn     = 0x20,   // seen a return statement
-    CSXany_ctor   = 0x40,   // either this() or super() was called
-    CSXhalt       = 0x80,   // assert(0)
+    none       = 0,
+    this_ctor  = 1,      // called this()
+    super_ctor = 2,      // called super()
+    label      = 4,      // seen a label
+    return_    = 8,      // seen a return statement
+    any_ctor   = 0x10,   // either this() or super() was called
+    halt       = 0x20,   // assert(0)
 };
 
-enum
+enum class SCOPE
 {
     // Flags that would not be inherited beyond scope nesting
-    SCOPEctor          = 0x0001,  // constructor type
-    SCOPEcondition     = 0x0004,  // inside static if/assert condition
-    SCOPEdebug         = 0x0008,  // inside debug conditional
+    ctor          = 0x0001,  // constructor type
+    noaccesscheck = 0x0002,  // don't do access checks
+    condition     = 0x0004,  // inside static if/assert condition
+    debug_        = 0x0008,  // inside debug conditional
 
     // Flags that would be inherited beyond scope nesting
-    SCOPEnoaccesscheck = 0x0002,  // don't do access checks
-    SCOPEconstraint    = 0x0010,  // inside template constraint
-    SCOPEinvariant     = 0x0020,  // inside invariant code
-    SCOPErequire       = 0x0040,  // inside in contract code
-    SCOPEensure        = 0x0060,  // inside out contract code
-    SCOPEcontract      = 0x0060,  // [mask] we're inside contract code
-    SCOPEctfe          = 0x0080,  // inside a ctfe-only expression
-    SCOPEcompile       = 0x0100,  // inside __traits(compile)
-    SCOPEignoresymbolvisibility = 0x0200,  // ignore symbol visibility (Bugzilla 15907)
-
-    SCOPEfree          = 0x8000,  // is on free list
-    SCOPEfullinst      = 0x10000, // fully instantiate templates
-    SCOPEalias         = 0x20000, // inside alias declaration
-
-    // The following are mutually exclusive
-    SCOPEprintf        = 0x40000, // printf-style function
-    SCOPEscanf         = 0x80000, // scanf-style function
+    constraint    = 0x0010,  // inside template constraint
+    invariant_    = 0x0020,  // inside invariant code
+    require       = 0x0040,  // inside in contract code
+    ensure        = 0x0060,  // inside out contract code
+    contract      = 0x0060,  // [mask] we're inside contract code
+    ctfe          = 0x0080,  // inside a ctfe-only expression
+    compile       = 0x0100,  // inside __traits(compile)
+    ignoresymbolvisibility = 0x0200,  // ignore symbol visibility (Bugzilla 15907)
+
+    Cfile         = 0x0800,  // C semantics apply
+    free          = 0x8000,  // is on free list
+    fullinst      = 0x10000, // fully instantiate templates
 };
 
 struct Scope
@@ -74,6 +69,7 @@ struct Scope
     Module *_module;            // Root module
     ScopeDsymbol *scopesym;     // current symbol
     FuncDeclaration *func;      // function we are in
+    VarDeclaration  *varDecl;   // variable we are in during semantic2
     Dsymbol *parent;            // parent to use
     LabelStatement *slabel;     // enclosing labelled statement
     SwitchStatement *sw;        // enclosing switch statement
@@ -98,8 +94,8 @@ struct Scope
     Module *minst;              // root module where the instantiated templates should belong to
     TemplateInstance *tinst;    // enclosing template instance
 
-    unsigned char callSuper;    // primitive flow analysis for constructors
-    unsigned char *fieldinit;
+    CSX callSuper;              // primitive flow analysis for constructors
+    CSX *fieldinit;
     size_t fieldinit_dim;
 
     AlignDeclaration *aligndecl;    // alignment for struct members
@@ -128,24 +124,6 @@ struct Scope
 
     AliasDeclaration *aliasAsg; // if set, then aliasAsg is being assigned a new value,
                                 // do not set wasRead for it
-    Scope();
-
-    Scope *copy();
-
-    Scope *push();
-    Scope *push(ScopeDsymbol *ss);
-    Scope *pop();
-
-    Scope *startCTFE();
-    Scope *endCTFE();
 
     Dsymbol *search(const Loc &loc, Identifier *ident, Dsymbol **pscopesym, int flags = IgnoreNone);
-
-    ClassDeclaration *getClassScope();
-    AggregateDeclaration *getStructClassScope();
-
-    structalign_t alignment();
-
-    bool isDeprecated() const;
-    bool isFromSpeculativeSemanticContext() const;
 };
diff --git a/gcc/d/dmd/semantic2.d b/gcc/d/dmd/semantic2.d
index bf18a2140fb..4795bcfcf6d 100644
--- a/gcc/d/dmd/semantic2.d
+++ b/gcc/d/dmd/semantic2.d
@@ -163,7 +163,7 @@ private extern(C++) final class Semantic2Visitor : Visitor
         if (needGagging)
             oldGaggedErrors = global.startGagging();
 
-        for (size_t i = 0; i < tempinst.members.dim; i++)
+        for (size_t i = 0; i < tempinst.members.length; i++)
         {
             Dsymbol s = (*tempinst.members)[i];
             static if (LOG)
@@ -211,7 +211,7 @@ private extern(C++) final class Semantic2Visitor : Visitor
         sc = sc.push(tmix);
         sc.tinst = tmix;
         sc.minst = tmix.minst;
-        for (size_t i = 0; i < tmix.members.dim; i++)
+        for (size_t i = 0; i < tmix.members.length; i++)
         {
             Dsymbol s = (*tmix.members)[i];
             static if (LOG)
@@ -230,6 +230,8 @@ private extern(C++) final class Semantic2Visitor : Visitor
             return;
 
         //printf("VarDeclaration::semantic2('%s')\n", toChars());
+        sc.varDecl = vd;
+        scope(exit) sc.varDecl = null;
 
         if (vd.aliassym)        // if it's a tuple
         {
@@ -333,7 +335,7 @@ private extern(C++) final class Semantic2Visitor : Visitor
         if (mod.members)
         {
             // Pass 2 semantic routines: do initializers and function bodies
-            for (size_t i = 0; i < mod.members.dim; i++)
+            for (size_t i = 0; i < mod.members.length; i++)
             {
                 Dsymbol s = (*mod.members)[i];
                 s.semantic2(sc);
@@ -520,7 +522,7 @@ private extern(C++) final class Semantic2Visitor : Visitor
             return;
 
         Scope* sc2 = ad.newScope(sc);
-        for (size_t i = 0; i < d.dim; i++)
+        for (size_t i = 0; i < d.length; i++)
         {
             Dsymbol s = (*d)[i];
             s.semantic2(sc2);
@@ -559,7 +561,7 @@ private extern(C++) final class Semantic2Visitor : Visitor
 
     override void visit(UserAttributeDeclaration uad)
     {
-        if (!uad.decl || !uad.atts || !uad.atts.dim || !uad._scope)
+        if (!uad.decl || !uad.atts || !uad.atts.length || !uad._scope)
             return visit(cast(AttribDeclaration)uad);
 
         Expression* lastTag;
@@ -609,7 +611,7 @@ private extern(C++) final class Semantic2Visitor : Visitor
 
         ad.determineSize(ad.loc);
 
-        for (size_t i = 0; i < ad.members.dim; i++)
+        for (size_t i = 0; i < ad.members.length; i++)
         {
             Dsymbol s = (*ad.members)[i];
             //printf("\t[%d] %s\n", i, s.toChars());
diff --git a/gcc/d/dmd/semantic3.d b/gcc/d/dmd/semantic3.d
index 8ea419a1f57..cc75aa51e5a 100644
--- a/gcc/d/dmd/semantic3.d
+++ b/gcc/d/dmd/semantic3.d
@@ -127,7 +127,7 @@ private extern(C++) final class Semantic3Visitor : Visitor
         if (needGagging)
             oldGaggedErrors = global.startGagging();
 
-        for (size_t i = 0; i < tempinst.members.dim; i++)
+        for (size_t i = 0; i < tempinst.members.length; i++)
         {
             Dsymbol s = (*tempinst.members)[i];
             s.semantic3(sc);
@@ -170,7 +170,7 @@ private extern(C++) final class Semantic3Visitor : Visitor
 
         uint olderrors = global.errors;
 
-        for (size_t i = 0; i < tmix.members.dim; i++)
+        for (size_t i = 0; i < tmix.members.length; i++)
         {
             Dsymbol s = (*tmix.members)[i];
             s.semantic3(sc);
@@ -197,7 +197,7 @@ private extern(C++) final class Semantic3Visitor : Visitor
         if (mod.members)
         {
             // Pass 3 semantic routines: do initializers and function bodies
-            for (size_t i = 0; i < mod.members.dim; i++)
+            for (size_t i = 0; i < mod.members.length; i++)
             {
                 Dsymbol s = (*mod.members)[i];
                 //printf("Module %s: %s.semantic3()\n", toChars(), s.toChars());
@@ -586,7 +586,7 @@ private extern(C++) final class Semantic3Visitor : Visitor
                  */
                 if (ad2 && funcdecl.isCtorDeclaration())
                 {
-                    sc2.ctorflow.allocFieldinit(ad2.fields.dim);
+                    sc2.ctorflow.allocFieldinit(ad2.fields.length);
                     foreach (v; ad2.fields)
                     {
                         v.ctorinit = 0;
@@ -624,7 +624,7 @@ private extern(C++) final class Semantic3Visitor : Visitor
 
                 if (funcdecl.returns && !funcdecl.fbody.isErrorStatement())
                 {
-                    for (size_t i = 0; i < funcdecl.returns.dim;)
+                    for (size_t i = 0; i < funcdecl.returns.length;)
                     {
                         Expression exp = (*funcdecl.returns)[i].exp;
                         if (exp.op == EXP.variable && (cast(VarExp)exp).var == funcdecl.vresult)
@@ -661,7 +661,7 @@ private extern(C++) final class Semantic3Visitor : Visitor
                      * ctor consts were initialized.
                      */
                     ScopeDsymbol pd = funcdecl.toParent().isScopeDsymbol();
-                    for (size_t i = 0; i < pd.members.dim; i++)
+                    for (size_t i = 0; i < pd.members.length; i++)
                     {
                         Dsymbol s = (*pd.members)[i];
                         s.checkCtorConstInit();
@@ -829,7 +829,7 @@ private extern(C++) final class Semantic3Visitor : Visitor
                     /* Cannot move this loop into NrvoWalker, because
                      * returns[i] may be in the nested delegate for foreach-body.
                      */
-                    for (size_t i = 0; i < funcdecl.returns.dim; i++)
+                    for (size_t i = 0; i < funcdecl.returns.length; i++)
                     {
                         ReturnStatement rs = (*funcdecl.returns)[i];
                         Expression exp = rs.exp;
@@ -1068,7 +1068,7 @@ private extern(C++) final class Semantic3Visitor : Visitor
                 // Merge in initialization of 'out' parameters
                 if (funcdecl.parameters)
                 {
-                    for (size_t i = 0; i < funcdecl.parameters.dim; i++)
+                    for (size_t i = 0; i < funcdecl.parameters.length; i++)
                     {
                         VarDeclaration v = (*funcdecl.parameters)[i];
                         if (v.storage_class & STC.out_)
@@ -1253,7 +1253,7 @@ private extern(C++) final class Semantic3Visitor : Visitor
             // Fix up forward-referenced gotos
             if (funcdecl.gotos && !funcdecl.isCsymbol())
             {
-                for (size_t i = 0; i < funcdecl.gotos.dim; ++i)
+                for (size_t i = 0; i < funcdecl.gotos.length; ++i)
                 {
                     (*funcdecl.gotos)[i].checkLabel();
                 }
@@ -1526,7 +1526,7 @@ private extern(C++) final class Semantic3Visitor : Visitor
             return;
 
         Scope* sc2 = ad.newScope(sc);
-        for (size_t i = 0; i < d.dim; i++)
+        for (size_t i = 0; i < d.length; i++)
         {
             Dsymbol s = (*d)[i];
             s.semantic3(sc2);
@@ -1551,7 +1551,7 @@ private extern(C++) final class Semantic3Visitor : Visitor
 
         auto sc2 = ad.newScope(sc);
 
-        for (size_t i = 0; i < ad.members.dim; i++)
+        for (size_t i = 0; i < ad.members.length; i++)
         {
             Dsymbol s = (*ad.members)[i];
             s.semantic3(sc2);
@@ -1612,7 +1612,7 @@ private struct FuncDeclSem3
     {
         if (funcdecl.frequires)
         {
-            for (size_t i = 0; i < funcdecl.foverrides.dim; i++)
+            for (size_t i = 0; i < funcdecl.foverrides.length; i++)
             {
                 FuncDeclaration fdv = funcdecl.foverrides[i];
                 if (fdv.fbody && !fdv.frequires)
diff --git a/gcc/d/dmd/statement.d b/gcc/d/dmd/statement.d
index a519f3b4c4c..91a802ecdd7 100644
--- a/gcc/d/dmd/statement.d
+++ b/gcc/d/dmd/statement.d
@@ -610,7 +610,7 @@ extern (C++) class CompoundStatement : Statement
     override final inout(Statement) last() inout nothrow pure
     {
         Statement s = null;
-        for (size_t i = statements.dim; i; --i)
+        for (size_t i = statements.length; i; --i)
         {
             s = cast(Statement)(*statements)[i - 1];
             if (s)
@@ -640,7 +640,7 @@ extern (C++) final class CompoundDeclarationStatement : CompoundStatement
 
     override CompoundDeclarationStatement syntaxCopy()
     {
-        auto a = new Statements(statements.dim);
+        auto a = new Statements(statements.length);
         foreach (i, s; *statements)
         {
             (*a)[i] = s ? s.syntaxCopy() : null;
@@ -670,7 +670,7 @@ extern (C++) final class UnrolledLoopStatement : Statement
 
     override UnrolledLoopStatement syntaxCopy()
     {
-        auto a = new Statements(statements.dim);
+        auto a = new Statements(statements.length);
         foreach (i, s; *statements)
         {
             (*a)[i] = s ? s.syntaxCopy() : null;
@@ -1571,7 +1571,7 @@ extern (C++) final class TryCatchStatement : Statement
 
     override TryCatchStatement syntaxCopy()
     {
-        auto a = new Catches(catches.dim);
+        auto a = new Catches(catches.length);
         foreach (i, c; *catches)
         {
             (*a)[i] = c.syntaxCopy();
@@ -2019,7 +2019,7 @@ extern (C++) final class CompoundAsmStatement : CompoundStatement
 
     override CompoundAsmStatement syntaxCopy()
     {
-        auto a = new Statements(statements.dim);
+        auto a = new Statements(statements.length);
         foreach (i, s; *statements)
         {
             (*a)[i] = s ? s.syntaxCopy() : null;
@@ -2048,7 +2048,7 @@ extern (C++) final class ImportStatement : Statement
 
     override ImportStatement syntaxCopy()
     {
-        auto m = new Dsymbols(imports.dim);
+        auto m = new Dsymbols(imports.length);
         foreach (i, s; *imports)
         {
             (*m)[i] = s.syntaxCopy(null);
diff --git a/gcc/d/dmd/statement_rewrite_walker.d b/gcc/d/dmd/statement_rewrite_walker.d
index b1f659d33ef..7b3a13b40bc 100644
--- a/gcc/d/dmd/statement_rewrite_walker.d
+++ b/gcc/d/dmd/statement_rewrite_walker.d
@@ -48,9 +48,9 @@ public:
 
     override void visit(CompoundStatement s)
     {
-        if (s.statements && s.statements.dim)
+        if (s.statements && s.statements.length)
         {
-            for (size_t i = 0; i < s.statements.dim; i++)
+            for (size_t i = 0; i < s.statements.length; i++)
             {
                 if ((*s.statements)[i])
                     visitStmt((*s.statements)[i]);
@@ -65,9 +65,9 @@ public:
 
     override void visit(UnrolledLoopStatement s)
     {
-        if (s.statements && s.statements.dim)
+        if (s.statements && s.statements.length)
         {
-            for (size_t i = 0; i < s.statements.dim; i++)
+            for (size_t i = 0; i < s.statements.length; i++)
             {
                 if ((*s.statements)[i])
                     visitStmt((*s.statements)[i]);
@@ -161,9 +161,9 @@ public:
     {
         if (s._body)
             visitStmt(s._body);
-        if (s.catches && s.catches.dim)
+        if (s.catches && s.catches.length)
         {
-            for (size_t i = 0; i < s.catches.dim; i++)
+            for (size_t i = 0; i < s.catches.length; i++)
             {
                 Catch c = (*s.catches)[i];
                 if (c && c.handler)
diff --git a/gcc/d/dmd/statementsem.d b/gcc/d/dmd/statementsem.d
index 4f9baf89dc2..b372fc2f5a9 100644
--- a/gcc/d/dmd/statementsem.d
+++ b/gcc/d/dmd/statementsem.d
@@ -249,7 +249,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
             }
         }
 
-        for (size_t i = 0; i < cs.statements.dim;)
+        for (size_t i = 0; i < cs.statements.length;)
         {
             Statement s = (*cs.statements)[i];
             if (!s)
@@ -312,7 +312,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
                     return true;
                 }
 
-                if (!sfinally && isEmpty((*cs.statements)[i + 1 .. cs.statements.dim]))
+                if (!sfinally && isEmpty((*cs.statements)[i + 1 .. cs.statements.length]))
                 {
                 }
                 else
@@ -358,7 +358,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
             }
             else if (sfinally)
             {
-                if (0 && i + 1 == cs.statements.dim)
+                if (0 && i + 1 == cs.statements.length)
                 {
                     cs.statements.push(sfinally);
                 }
@@ -645,6 +645,13 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
             CommaExp.allow(fs.increment);
             fs.increment = fs.increment.expressionSemantic(sc);
             fs.increment = resolveProperties(sc, fs.increment);
+            // @@@DEPRECATED_2.112@@@
+            // remove gagging and deprecation() to turn deprecation into an error when
+            // deprecation cycle is over
+            const olderrors = global.startGagging();
+            discardValue(fs.increment);
+            if (global.endGagging(olderrors))
+                fs.increment.deprecation("`%s` has no effect", fs.increment.toChars());
             if (checkNonAssignmentArrayOp(fs.increment))
                 fs.increment = ErrorExp.get();
             fs.increment = fs.increment.optimize(WANTvalue);
@@ -693,7 +700,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
         }
 
         const loc = fs.loc;
-        const dim = fs.parameters.dim;
+        const dim = fs.parameters.length;
 
         fs.func = sc.func;
         if (fs.func.fes)
@@ -791,7 +798,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
                 }
             }
 
-            //printf("dim = %d, parameters.dim = %d\n", dim, parameters.dim);
+            //printf("dim = %d, parameters.length = %d\n", dim, parameters.length);
             if (foundMismatch && dim != foreachParamCount)
             {
                 const(char)* plural = foreachParamCount > 1 ? "s" : "";
@@ -854,7 +861,6 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
             result = s;
         }
 
-        TypeAArray taa = null;
         Type tn = null;
         Type tnv = null;
         Statement apply()
@@ -865,26 +871,25 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
             TypeFunction tfld = null;
             if (sapply)
             {
-                FuncDeclaration fdapply = sapply.isFuncDeclaration();
-                if (fdapply)
+                if (auto fdapply = sapply.isFuncDeclaration())
                 {
-                    assert(fdapply.type && fdapply.type.ty == Tfunction);
-                    tfld = cast(TypeFunction)fdapply.type.typeSemantic(loc, sc2);
+                    assert(fdapply.type && fdapply.type.isTypeFunction());
+                    tfld = fdapply.type.typeSemantic(loc, sc2).isTypeFunction();
                     goto Lget;
                 }
-                else if (tab.ty == Tdelegate)
+                else if (tab.isTypeDelegate())
                 {
-                    tfld = cast(TypeFunction)tab.nextOf();
+                    tfld = tab.nextOf().isTypeFunction();
                 Lget:
                     //printf("tfld = %s\n", tfld.toChars());
-                    if (tfld.parameterList.parameters.dim == 1)
+                    if (tfld.parameterList.parameters.length == 1)
                     {
                         Parameter p = tfld.parameterList[0];
-                        if (p.type && p.type.ty == Tdelegate)
+                        if (p.type && p.type.isTypeDelegate())
                         {
                             auto t = p.type.typeSemantic(loc, sc2);
                             assert(t.ty == Tdelegate);
-                            tfld = cast(TypeFunction)t.nextOf();
+                            tfld = t.nextOf().isTypeFunction();
                         }
                     }
                 }
@@ -902,12 +907,11 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
                 {
                     // 'Promote' it to this scope, and replace with a return
                     fs.cases.push(gs);
-                    ss.statement = new ReturnStatement(Loc.initial, new IntegerExp(fs.cases.dim + 1));
+                    ss.statement = new ReturnStatement(Loc.initial, new IntegerExp(fs.cases.length + 1));
                 }
             }
 
             Expression e = null;
-            Expression ec;
             if (vinit)
             {
                 e = new DeclarationExp(loc, vinit);
@@ -916,19 +920,22 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
                     return null;
             }
 
-            if (taa)
-                ec = applyAssocArray(fs, flde, taa);
-            else if (tab.ty == Tarray || tab.ty == Tsarray)
-                ec = applyArray(fs, flde, sc2, tn, tnv, tab.ty);
-            else if (tab.ty == Tdelegate)
-                ec = applyDelegate(fs, flde, sc2, tab);
-            else
-                ec = applyOpApply(fs, tab, sapply, sc2, flde);
+            Expression ec;
+            switch (tab.ty)
+            {
+                case Tarray:
+                case Tsarray:   ec = applyArray     (fs, flde, tab, sc2, tn, tnv); break;
+                case Tdelegate: ec = applyDelegate  (fs, flde, tab, sc2);          break;
+                case Taarray:   ec = applyAssocArray(fs, flde, tab);               break;
+                default:        ec = applyOpApply   (fs, flde, tab, sc2, sapply);  break;
+            }
             if (!ec)
                 return null;
+
             e = Expression.combine(e, ec);
             return loopReturn(e, fs.cases, loc);
         }
+
         switch (tab.ty)
         {
         case Tarray:
@@ -966,7 +973,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
                      *  2. foreach body is lowered to _aApply (see special case below).
                      */
                     Type tv = (*fs.parameters)[1].type.toBasetype();
-                    if ((tab.ty == Tarray ||
+                    if ((tab.isTypeDArray() ||
                          (tn.ty != tv.ty && tn.ty.isSomeChar && tv.ty.isSomeChar)) &&
                         !Type.tsize_t.implicitConvTo(tindex))
                     {
@@ -1021,9 +1028,8 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
                             return retError();
                         }
                     }
-                    if (tab.ty == Tsarray)
+                    if (auto ta = tab.isTypeSArray())
                     {
-                        TypeSArray ta = cast(TypeSArray)tab;
                         IntRange dimrange = getIntRange(ta.dim);
                         // https://issues.dlang.org/show_bug.cgi?id=12504
                         dimrange.imax = SignExtendedNumber(dimrange.imax.value-1);
@@ -1072,10 +1078,10 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
                 auto ie = new ExpInitializer(loc, new SliceExp(loc, fs.aggr, null, null));
                 const valueIsRef = (*fs.parameters)[$ - 1].isReference();
                 VarDeclaration tmp;
-                if (fs.aggr.op == EXP.arrayLiteral && !valueIsRef)
+                if (fs.aggr.isArrayLiteralExp() && !valueIsRef)
                 {
-                    auto ale = cast(ArrayLiteralExp)fs.aggr;
-                    size_t edim = ale.elements ? ale.elements.dim : 0;
+                    auto ale = fs.aggr.isArrayLiteralExp();
+                    size_t edim = ale.elements ? ale.elements.length : 0;
                     auto telem = (*fs.parameters)[dim - 1].type;
 
                     // https://issues.dlang.org/show_bug.cgi?id=12936
@@ -1182,7 +1188,6 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
             if (checkForArgTypes(fs))
                 return retError();
 
-            taa = cast(TypeAArray)tab;
             if (dim < 1 || dim > 2)
             {
                 fs.error("only one or two arguments for associative array `foreach`");
@@ -1207,8 +1212,8 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
                  *    }
                  */
                 auto ad = (tab.ty == Tclass) ?
-                    cast(AggregateDeclaration)(cast(TypeClass)tab).sym :
-                    cast(AggregateDeclaration)(cast(TypeStruct)tab).sym;
+                    cast(AggregateDeclaration)tab.isTypeClass().sym :
+                    cast(AggregateDeclaration)tab.isTypeStruct().sym;
                 Identifier idfront;
                 Identifier idpopFront;
                 if (fs.op == TOK.foreach_)
@@ -1229,7 +1234,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
                  */
                 VarDeclaration r;
                 Statement _init;
-                if (vinit && fs.aggr.op == EXP.variable && (cast(VarExp)fs.aggr).var == vinit)
+                if (vinit && fs.aggr.isVarExp() && fs.aggr.isVarExp().var == vinit)
                 {
                     r = vinit;
                     _init = new ExpStatement(loc, vinit);
@@ -1279,9 +1284,8 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
                 }
                 if (!tfront || tfront.ty == Terror)
                     return rangeError();
-                if (tfront.toBasetype().ty == Tfunction)
+                if (auto ftt = tfront.toBasetype().isTypeFunction())
                 {
-                    auto ftt = cast(TypeFunction)tfront.toBasetype();
                     tfront = tfront.toBasetype().nextOf();
                     if (!ftt.isref)
                     {
@@ -1323,17 +1327,17 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
                     auto exps = new Expressions();
                     exps.push(ve);
                     int pos = 0;
-                    while (exps.dim < dim)
+                    while (exps.length < dim)
                     {
                         pos = expandAliasThisTuples(exps, pos);
                         if (pos == -1)
                             break;
                     }
-                    if (exps.dim != dim)
+                    if (exps.length != dim)
                     {
-                        const(char)* plural = exps.dim > 1 ? "s" : "";
+                        const(char)* plural = exps.length > 1 ? "s" : "";
                         fs.error("cannot infer argument types, expected %llu argument%s, not %llu",
-                            cast(ulong) exps.dim, plural, cast(ulong) dim);
+                            cast(ulong) exps.length, plural, cast(ulong) dim);
                         return retError();
                     }
 
@@ -1389,8 +1393,8 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
         }
     }
 
-    private static extern(D) Expression applyOpApply(ForeachStatement fs, Type tab, Dsymbol sapply,
-                                                     Scope* sc2, Expression flde)
+    private static extern(D) Expression applyOpApply(ForeachStatement fs, Expression flde,
+                Type tab, Scope* sc2, Dsymbol sapply)
     {
         version (none)
         {
@@ -1425,7 +1429,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
     }
 
     private static extern(D) Expression applyDelegate(ForeachStatement fs, Expression flde,
-                                                      Scope* sc2, Type tab)
+                                                      Type tab, Scope* sc2)
     {
         Expression ec;
         /* Call:
@@ -1450,10 +1454,10 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
     }
 
     private static extern(D) Expression applyArray(ForeachStatement fs, Expression flde,
-                                                   Scope* sc2, Type tn, Type tnv, TY tabty)
+                                                   Type tab, Scope* sc2, Type tn, Type tnv)
     {
         Expression ec;
-        const dim = fs.parameters.dim;
+        const dim = fs.parameters.length;
         const loc = fs.loc;
         /* Call:
          *      _aApply(aggr, flde)
@@ -1501,7 +1505,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
         params.push(new Parameter(0, dgty, null, null, null));
         fdapply = FuncDeclaration.genCfunc(params, Type.tint32, fdname.ptr);
 
-        if (tabty == Tsarray)
+        if (tab.isTypeSArray())
             fs.aggr = fs.aggr.castTo(sc2, tn.arrayOf());
         // paint delegate argument to the type runtime expects
         Expression fexp = flde;
@@ -1516,10 +1520,11 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
         return ec;
     }
 
-    private static extern(D) Expression applyAssocArray(ForeachStatement fs, Expression flde, TypeAArray taa)
+    private static extern(D) Expression applyAssocArray(ForeachStatement fs, Expression flde, Type tab)
     {
+        auto taa = tab.isTypeAArray();
         Expression ec;
-        const dim = fs.parameters.dim;
+        const dim = fs.parameters.length;
         // Check types
         Parameter p = (*fs.parameters)[0];
         bool isRef = (p.storageClass & STC.ref_) != 0;
@@ -1593,7 +1598,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
 
     private static extern(D) Statement loopReturn(Expression e, Statements* cases, const ref Loc loc)
     {
-        if (!cases.dim)
+        if (!cases.length)
         {
             // Easy case, a clean exit from the loop
             e = new CastExp(loc, e, Type.tvoid); // https://issues.dlang.org/show_bug.cgi?id=13899
@@ -2024,7 +2029,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
             }
             else
             {
-                if (!ps.args || ps.args.dim != 1)
+                if (!ps.args || ps.args.length != 1)
                 {
                     ps.error("`string` expected for library name");
                     return setError();
@@ -2338,7 +2343,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
 
         size_t numcases = 0;
         if (ss.cases)
-            numcases = ss.cases.dim;
+            numcases = ss.cases.length;
 
         for (size_t i = 0; i < numcases; i++)
         {
@@ -2501,7 +2506,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
             sw.cases.push(cs);
 
             // Resolve any goto case's with no exp to this case statement
-            for (size_t i = 0; i < sw.gotoCases.dim;)
+            for (size_t i = 0; i < sw.gotoCases.length;)
             {
                 GotoCaseStatement gcs = sw.gotoCases[i];
                 if (!gcs.exp)
@@ -2735,7 +2740,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
             {
                 assert(rs.caseDim == 0);
                 sc.fes.cases.push(rs);
-                result = new ReturnStatement(Loc.initial, new IntegerExp(sc.fes.cases.dim + 1));
+                result = new ReturnStatement(Loc.initial, new IntegerExp(sc.fes.cases.length + 1));
                 return;
             }
             if (fd.returnLabel)
@@ -3053,8 +3058,8 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
                 sc.fes.cases.push(s);
 
                 // Immediately rewrite "this" return statement as:
-                //  return cases.dim+1;
-                rs.exp = new IntegerExp(sc.fes.cases.dim + 1);
+                //  return cases.length+1;
+                rs.exp = new IntegerExp(sc.fes.cases.length + 1);
                 if (e0)
                 {
                     result = new CompoundStatement(rs.loc, new ExpStatement(rs.loc, e0), rs);
@@ -3078,7 +3083,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
                 //  return exp;
                 // to:
                 //  vresult = exp; retrun caseDim;
-                rs.caseDim = sc.fes.cases.dim + 1;
+                rs.caseDim = sc.fes.cases.length + 1;
             }
         }
         if (rs.exp)
@@ -3136,7 +3141,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
                          * and 1 is break.
                          */
                         sc.fes.cases.push(bs);
-                        result = new ReturnStatement(Loc.initial, new IntegerExp(sc.fes.cases.dim + 1));
+                        result = new ReturnStatement(Loc.initial, new IntegerExp(sc.fes.cases.length + 1));
                         return;
                     }
                     break; // can't break to it
@@ -3224,7 +3229,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
                          * and 1 is break.
                          */
                         sc.fes.cases.push(cs);
-                        result = new ReturnStatement(Loc.initial, new IntegerExp(sc.fes.cases.dim + 1));
+                        result = new ReturnStatement(Loc.initial, new IntegerExp(sc.fes.cases.length + 1));
                         return;
                     }
                     break; // can't continue to it
@@ -3589,7 +3594,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
          */
         if (!(tcs._body.blockExit(sc.func, false) & BE.throw_) && ClassDeclaration.exception)
         {
-            foreach_reverse (i; 0 .. tcs.catches.dim)
+            foreach_reverse (i; 0 .. tcs.catches.length)
             {
                 Catch c = (*tcs.catches)[i];
 
@@ -3604,7 +3609,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
             }
         }
 
-        if (tcs.catches.dim == 0)
+        if (tcs.catches.length == 0)
         {
             result = tcs._body.hasCode() ? tcs._body : null;
             return;
@@ -3909,10 +3914,10 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
         /* https://dlang.org/spec/module.html#ImportDeclaration
          */
 
-        foreach (i; 0 .. imps.imports.dim)
+        foreach (i; 0 .. imps.imports.length)
         {
             Import s = (*imps.imports)[i].isImport();
-            assert(!s.aliasdecls.dim);
+            assert(!s.aliasdecls.length);
             foreach (j, name; s.names)
             {
                 Identifier _alias = s.aliases[j];
@@ -4217,7 +4222,7 @@ public auto makeTupleForeach(Scope* sc, bool isStatic, bool isDecl, ForeachState
     }
 
     auto loc = fs.loc;
-    size_t dim = fs.parameters.dim;
+    size_t dim = fs.parameters.length;
     const bool skipCheck = isStatic && needExpansion;
     if (!skipCheck && (dim < 1 || dim > 2))
     {
@@ -4251,7 +4256,7 @@ public auto makeTupleForeach(Scope* sc, bool isStatic, bool isDecl, ForeachState
     if (fs.aggr.op == EXP.tuple) // expression tuple
     {
         te = cast(TupleExp)fs.aggr;
-        n = te.exps.dim;
+        n = te.exps.length;
     }
     else if (fs.aggr.op == EXP.type) // type tuple
     {
@@ -4632,7 +4637,7 @@ private Statements* flatten(Statement statement, Scope* sc)
             {
                 return a;
             }
-            auto b = new Statements(a.dim);
+            auto b = new Statements(a.length);
             foreach (i, s; *a)
             {
                 (*b)[i] = s ? new ForwardingStatement(s.loc, fs.sym, s) : null;
@@ -4702,7 +4707,7 @@ private Statements* flatten(Statement statement, Scope* sc)
             if (!a)
                 return null;
 
-            if (!a.dim)
+            if (!a.length)
             {
                 a.push(new ExpStatement(ls.loc, cast(Expression)null));
             }
@@ -4892,7 +4897,7 @@ bool pragmaMsgSemantic(Loc loc, Scope* sc, Expressions* args)
  */
 bool pragmaStartAddressSemantic(Loc loc, Scope* sc, Expressions* args)
 {
-    if (!args || args.dim != 1)
+    if (!args || args.length != 1)
     {
         .error(loc, "function name expected for start address");
         return false;
diff --git a/gcc/d/dmd/traits.d b/gcc/d/dmd/traits.d
index 367c56b7918..a6d2304c38a 100644
--- a/gcc/d/dmd/traits.d
+++ b/gcc/d/dmd/traits.d
@@ -394,7 +394,7 @@ ulong getTypePointerBitmap(Loc loc, Type t, Array!(ulong)* data)
  */
 private Expression pointerBitmap(TraitsExp e)
 {
-    if (!e.args || e.args.dim != 1)
+    if (!e.args || e.args.length != 1)
     {
         error(e.loc, "a single type expected for trait pointerBitmap");
         return ErrorExp.get();
@@ -412,12 +412,12 @@ private Expression pointerBitmap(TraitsExp e)
     if (sz == ulong.max)
         return ErrorExp.get();
 
-    auto exps = new Expressions(data.dim + 1);
+    auto exps = new Expressions(data.length + 1);
     (*exps)[0] = new IntegerExp(e.loc, sz, Type.tsize_t);
-    foreach (size_t i; 1 .. exps.dim)
+    foreach (size_t i; 1 .. exps.length)
         (*exps)[i] = new IntegerExp(e.loc, data[cast(size_t) (i - 1)], Type.tsize_t);
 
-    auto ale = new ArrayLiteralExp(e.loc, Type.tsize_t.sarrayOf(data.dim + 1), exps);
+    auto ale = new ArrayLiteralExp(e.loc, Type.tsize_t.sarrayOf(data.length + 1), exps);
     return ale;
 }
 
@@ -446,7 +446,7 @@ Expression semanticTraits(TraitsExp e, Scope* sc)
         }
         sc.stc = save;
     }
-    size_t dim = e.args ? e.args.dim : 0;
+    size_t dim = e.args ? e.args.length : 0;
 
     Expression dimError(int expected)
     {
@@ -1276,6 +1276,25 @@ Expression semanticTraits(TraitsExp e, Scope* sc)
         }
         else if (s)
         {
+            // @@@DEPRECATION 2.100.2
+            if (auto fd = s.isFuncDeclaration())
+            {
+                if (fd.overnext)
+                {
+                    deprecation(e.loc, "`__traits(getAttributes)` may only be used for individual functions, not overload sets such as: `%s`", fd.toChars());
+                    deprecationSupplemental(e.loc, "the result of `__traits(getOverloads)` may be used to select the desired function to extract attributes from");
+                }
+            }
+
+            // @@@DEPRECATION 2.100.2
+            if (auto td = s.isTemplateDeclaration())
+            {
+                if (td.overnext || td.funcroot)
+                {
+                    deprecation(e.loc, "`__traits(getAttributes)` may only be used for individual functions, not overload sets such as: `%s`", td.ident.toChars());
+                    deprecationSupplemental(e.loc, "the result of `__traits(getOverloads)` may be used to select the desired function to extract attributes from");
+                }
+            }
             if (s.isImport())
             {
                 s = s.isImport().mod;
@@ -1689,12 +1708,12 @@ Expression semanticTraits(TraitsExp e, Scope* sc)
 
             void pushBaseMembersDg(ClassDeclaration cd)
             {
-                for (size_t i = 0; i < cd.baseclasses.dim; i++)
+                for (size_t i = 0; i < cd.baseclasses.length; i++)
                 {
                     auto cb = (*cd.baseclasses)[i].sym;
                     assert(cb);
                     ScopeDsymbol._foreach(null, cb.members, &pushIdentsDg);
-                    if (cb.baseclasses.dim)
+                    if (cb.baseclasses.length)
                         pushBaseMembersDg(cb);
                 }
             }
@@ -1801,9 +1820,9 @@ Expression semanticTraits(TraitsExp e, Scope* sc)
             return ErrorExp.get();
         if (!TemplateInstance.semanticTiargs(e.loc, sc, &ob2, 0))
             return ErrorExp.get();
-        if (ob1.dim != ob2.dim)
+        if (ob1.length != ob2.length)
             return False();
-        foreach (immutable i; 0 .. ob1.dim)
+        foreach (immutable i; 0 .. ob1.length)
             if (!ob1[i].isSame(ob2[i], sc))
                 return False();
         return True();
@@ -1924,7 +1943,12 @@ Expression semanticTraits(TraitsExp e, Scope* sc)
             return ErrorExp.get();
         }
 
-        Type tb = t.baseElemOf();
+        // https://issues.dlang.org/show_bug.cgi?id=23534
+        //
+        // For enums, we need to get the enum initializer
+        // (the first enum member), not the initializer of the
+        // type of the enum members.
+        Type tb = t.isTypeEnum ? t : t.baseElemOf();
         return tb.isZeroInit(e.loc) ? True() : False();
     }
     if (e.ident == Id.getTargetInfo)
@@ -2041,7 +2065,7 @@ Expression semanticTraits(TraitsExp e, Scope* sc)
                 if (prependNamespaces(outer, pp.cppnamespace)) return ErrorExp.get();
 
                 size_t i = 0;
-                while(i < outer.dim && ((*inner)[i]) == (*outer)[i])
+                while(i < outer.length && ((*inner)[i]) == (*outer)[i])
                     i++;
 
                 foreach_reverse (ns; (*inner)[][i .. $])
@@ -2124,7 +2148,7 @@ private bool isSame(RootObject o1, RootObject o2, Scope* sc)
         {
             if (auto td = t.isTemplateDeclaration())
             {
-                if (td.members && td.members.dim == 1)
+                if (td.members && td.members.length == 1)
                 {
                     if (auto fd = (*td.members)[0].isFuncLiteralDeclaration())
                         return fd;
@@ -2221,7 +2245,7 @@ private bool isSame(RootObject o1, RootObject o2, Scope* sc)
     if (!overSet2)
         return false;
 
-    if (overSet1.a.dim != overSet2.a.dim)
+    if (overSet1.a.length != overSet2.a.length)
         return false;
 
     // OverloadSets contain array of Dsymbols => O(n*n)
diff --git a/gcc/d/dmd/transitivevisitor.d b/gcc/d/dmd/transitivevisitor.d
index cbe6daa35a4..7aaf0b87268 100644
--- a/gcc/d/dmd/transitivevisitor.d
+++ b/gcc/d/dmd/transitivevisitor.d
@@ -617,7 +617,7 @@ package mixin template ParseVisitMethods(AST)
     void visitBaseClasses(AST.ClassDeclaration d)
     {
         //printf("Visiting ClassDeclaration\n");
-        if (!d || !d.baseclasses.dim)
+        if (!d || !d.baseclasses.length)
             return;
         foreach (b; *d.baseclasses)
             visitType(b.type);
@@ -626,7 +626,7 @@ package mixin template ParseVisitMethods(AST)
     bool visitEponymousMember(AST.TemplateDeclaration d)
     {
         //printf("Visiting EponymousMember\n");
-        if (!d.members || d.members.dim != 1)
+        if (!d.members || d.members.length != 1)
             return false;
         AST.Dsymbol onemember = (*d.members)[0];
         if (onemember.ident != d.ident)
@@ -688,7 +688,7 @@ package mixin template ParseVisitMethods(AST)
 
     void visitTemplateParameters(AST.TemplateParameters* parameters)
     {
-        if (!parameters || !parameters.dim)
+        if (!parameters || !parameters.length)
             return;
         foreach (p; *parameters)
             p.accept(this);
@@ -1042,7 +1042,7 @@ package mixin template ParseVisitMethods(AST)
         visitType(e.targ);
         if (e.tspec)
             visitType(e.tspec);
-        if (e.parameters && e.parameters.dim)
+        if (e.parameters && e.parameters.length)
             visitTemplateParameters(e.parameters);
     }
 
diff --git a/gcc/d/dmd/typesem.d b/gcc/d/dmd/typesem.d
index 0ef77052ec8..a75b4165cc3 100644
--- a/gcc/d/dmd/typesem.d
+++ b/gcc/d/dmd/typesem.d
@@ -117,9 +117,9 @@ private void resolveTupleIndex(const ref Loc loc, Scope* sc, Dsymbol s, out Expr
         return;
     }
     const(uinteger_t) d = eindex.toUInteger();
-    if (d >= tup.objects.dim)
+    if (d >= tup.objects.length)
     {
-        .error(loc, "tuple index `%llu` out of bounds `[0 .. %llu]`", d, cast(ulong)tup.objects.dim);
+        .error(loc, "tuple index `%llu` out of bounds `[0 .. %llu]`", d, cast(ulong)tup.objects.length);
         pt = Type.terror;
         return;
     }
@@ -194,7 +194,7 @@ private void resolveHelper(TypeQualified mt, const ref Loc loc, Scope* sc, Dsymb
     }
     s = s.toAlias();
     //printf("\t2: s = '%s' %p, kind = '%s'\n",s.toChars(), s, s.kind());
-    for (size_t i = 0; i < mt.idents.dim; i++)
+    for (size_t i = 0; i < mt.idents.length; i++)
     {
         RootObject id = mt.idents[i];
         switch (id.dyncast()) with (DYNCAST)
@@ -552,9 +552,9 @@ extern(C++) Type typeSemantic(Type type, const ref Loc loc, Scope* sc)
                 return error();
 
             uinteger_t d = mtype.dim.toUInteger();
-            if (d >= tup.objects.dim)
+            if (d >= tup.objects.length)
             {
-                .error(loc, "tuple index `%llu` out of bounds `[0 .. %llu]`", cast(ulong)d, cast(ulong)tup.objects.dim);
+                .error(loc, "tuple index `%llu` out of bounds `[0 .. %llu]`", cast(ulong)d, cast(ulong)tup.objects.length);
                 return error();
             }
 
@@ -647,9 +647,9 @@ extern(C++) Type typeSemantic(Type type, const ref Loc loc, Scope* sc)
                 assert(mtype.dim);
                 TypeTuple tt = tbn.isTypeTuple();
                 uinteger_t d = mtype.dim.toUInteger();
-                if (d >= tt.arguments.dim)
+                if (d >= tt.arguments.length)
                 {
-                    .error(loc, "tuple index `%llu` out of bounds `[0 .. %llu]`", cast(ulong)d, cast(ulong)tt.arguments.dim);
+                    .error(loc, "tuple index `%llu` out of bounds `[0 .. %llu]`", cast(ulong)d, cast(ulong)tt.arguments.length);
                     return error();
                 }
                 Type telem = (*tt.arguments)[cast(size_t)d].type;
@@ -875,11 +875,11 @@ extern(C++) Type typeSemantic(Type type, const ref Loc loc, Scope* sc)
                 fhash = search_function(ClassDeclaration.object, Id.tohash).isFuncDeclaration();
             assert(fcmp && feq && fhash);
 
-            if (feq.vtblIndex < cd.vtbl.dim && cd.vtbl[feq.vtblIndex] == feq)
+            if (feq.vtblIndex < cd.vtbl.length && cd.vtbl[feq.vtblIndex] == feq)
             {
                 version (all)
                 {
-                    if (fcmp.vtblIndex < cd.vtbl.dim && cd.vtbl[fcmp.vtblIndex] != fcmp)
+                    if (fcmp.vtblIndex < cd.vtbl.length && cd.vtbl[fcmp.vtblIndex] != fcmp)
                     {
                         const(char)* s = (mtype.index.toBasetype().ty != Tclass) ? "bottom of " : "";
                         .error(loc, "%sAA key type `%s` now requires equality rather than comparison", s, cd.toChars());
@@ -993,7 +993,7 @@ extern(C++) Type typeSemantic(Type type, const ref Loc loc, Scope* sc)
         if (mtype.parameterList.parameters)
         {
             tf.parameterList.parameters = mtype.parameterList.parameters.copy();
-            for (size_t i = 0; i < mtype.parameterList.parameters.dim; i++)
+            for (size_t i = 0; i < mtype.parameterList.parameters.length; i++)
             {
                 Parameter p = cast(Parameter)mem.xmalloc(__traits(classInstanceSize, Parameter));
                 memcpy(cast(void*)p, cast(void*)(*mtype.parameterList.parameters)[i], __traits(classInstanceSize, Parameter));
@@ -1180,13 +1180,13 @@ extern(C++) Type typeSemantic(Type type, const ref Loc loc, Scope* sc)
                      * the elements of TypeTuple::arguments to avoid unintended
                      * sharing of Parameter object among other functions.
                      */
-                    if (tt.arguments && tt.arguments.dim)
+                    if (tt.arguments && tt.arguments.length)
                     {
                         /* Propagate additional storage class from tuple parameters to their
                          * element-parameters.
                          * Make a copy, as original may be referenced elsewhere.
                          */
-                        size_t tdim = tt.arguments.dim;
+                        size_t tdim = tt.arguments.length;
                         auto newparams = new Parameters(tdim);
                         for (size_t j = 0; j < tdim; j++)
                         {
@@ -1437,7 +1437,7 @@ extern(C++) Type typeSemantic(Type type, const ref Loc loc, Scope* sc)
                  */
                 if (eparam.storageClass & STC.auto_)
                 {
-                    Expression farg = mtype.fargs && eidx < mtype.fargs.dim ?
+                    Expression farg = mtype.fargs && eidx < mtype.fargs.length ?
                         (*mtype.fargs)[eidx] : eparam.defaultArg;
                     if (farg && (eparam.storageClass & STC.ref_))
                     {
@@ -1756,10 +1756,10 @@ extern(C++) Type typeSemantic(Type type, const ref Loc loc, Scope* sc)
 
         uinteger_t i1 = mtype.lwr.toUInteger();
         uinteger_t i2 = mtype.upr.toUInteger();
-        if (!(i1 <= i2 && i2 <= tt.arguments.dim))
+        if (!(i1 <= i2 && i2 <= tt.arguments.length))
         {
             .error(loc, "slice `[%llu..%llu]` is out of range of `[0..%llu]`",
-                cast(ulong)i1, cast(ulong)i2, cast(ulong)tt.arguments.dim);
+                cast(ulong)i1, cast(ulong)i2, cast(ulong)tt.arguments.length);
             return error();
         }
 
@@ -2477,7 +2477,7 @@ Expression getProperty(Type t, Scope* scope_, const ref Loc loc, Identifier iden
         }
         if (ident == Id.length)
         {
-            e = new IntegerExp(loc, mt.arguments.dim, Type.tsize_t);
+            e = new IntegerExp(loc, mt.arguments.length, Type.tsize_t);
         }
         else if (ident == Id._init)
         {
@@ -2614,9 +2614,9 @@ void resolve(Type mt, const ref Loc loc, Scope* sc, out Expression pe, out Type
                     return returnError();
 
                 const d = mt.dim.toUInteger();
-                if (d >= tup.objects.dim)
+                if (d >= tup.objects.length)
                 {
-                    error(loc, "tuple index `%llu` out of bounds `[0 .. %llu]`", d, cast(ulong) tup.objects.dim);
+                    error(loc, "tuple index `%llu` out of bounds `[0 .. %llu]`", d, cast(ulong) tup.objects.length);
                     return returnError();
                 }
 
@@ -2897,7 +2897,7 @@ void resolve(Type mt, const ref Loc loc, Scope* sc, out Expression pe, out Type
             error(loc, "forward reference to `%s`", mt.toChars());
             goto Lerr;
         }
-        if (mt.idents.dim == 0)
+        if (mt.idents.length == 0)
         {
             returnType(t.addMod(mt.mod));
         }
@@ -2937,7 +2937,7 @@ void resolve(Type mt, const ref Loc loc, Scope* sc, out Expression pe, out Type
                 return returnError();
             }
         }
-        if (mt.idents.dim == 0)
+        if (mt.idents.length == 0)
         {
             return returnType(t.addMod(mt.mod));
         }
@@ -2987,13 +2987,13 @@ void resolve(Type mt, const ref Loc loc, Scope* sc, out Expression pe, out Type
                 mt.upr = mt.upr.ctfeInterpret();
                 const i1 = mt.lwr.toUInteger();
                 const i2 = mt.upr.toUInteger();
-                if (!(i1 <= i2 && i2 <= td.objects.dim))
+                if (!(i1 <= i2 && i2 <= td.objects.length))
                 {
-                    error(loc, "slice `[%llu..%llu]` is out of range of [0..%llu]", i1, i2, cast(ulong) td.objects.dim);
+                    error(loc, "slice `[%llu..%llu]` is out of range of [0..%llu]", i1, i2, cast(ulong) td.objects.length);
                     return returnError();
                 }
 
-                if (i1 == 0 && i2 == td.objects.dim)
+                if (i1 == 0 && i2 == td.objects.length)
                 {
                     return returnSymbol(td);
                 }
@@ -3002,7 +3002,7 @@ void resolve(Type mt, const ref Loc loc, Scope* sc, out Expression pe, out Type
                  * is a slice [i1..i2] out of the old one.
                  */
                 auto objects = new Objects(cast(size_t)(i2 - i1));
-                for (size_t i = 0; i < objects.dim; i++)
+                for (size_t i = 0; i < objects.length; i++)
                 {
                     (*objects)[i] = (*td.objects)[cast(size_t)i1 + i];
                 }
@@ -3096,8 +3096,8 @@ void resolve(Type mt, const ref Loc loc, Scope* sc, out Expression pe, out Type
                 break;
             case EXP.tuple:
                 TupleExp te = e.isTupleExp();
-                Objects* elems = new Objects(te.exps.dim);
-                foreach (i; 0 .. elems.dim)
+                Objects* elems = new Objects(te.exps.length);
+                foreach (i; 0 .. elems.length)
                 {
                     auto src = (*te.exps)[i];
                     switch (src.op)
@@ -3757,8 +3757,8 @@ Expression dotExp(Type mt, Scope* sc, Expression e, Identifier ident, int flag)
                 ev = extractSideEffect(sc, "__tup", e0, ev);
 
             auto exps = new Expressions();
-            exps.reserve(mt.sym.fields.dim);
-            for (size_t i = 0; i < mt.sym.fields.dim; i++)
+            exps.reserve(mt.sym.fields.length);
+            for (size_t i = 0; i < mt.sym.fields.length; i++)
             {
                 VarDeclaration v = mt.sym.fields[i];
                 Expression ex;
@@ -4015,8 +4015,8 @@ Expression dotExp(Type mt, Scope* sc, Expression e, Identifier ident, int flag)
                 ev = extractSideEffect(sc, "__tup", e0, ev);
 
             auto exps = new Expressions();
-            exps.reserve(mt.sym.fields.dim);
-            for (size_t i = 0; i < mt.sym.fields.dim; i++)
+            exps.reserve(mt.sym.fields.length);
+            for (size_t i = 0; i < mt.sym.fields.length; i++)
             {
                 VarDeclaration v = mt.sym.fields[i];
                 // Don't include hidden 'this' pointer
@@ -4589,8 +4589,8 @@ extern (C++) Expression defaultInit(Type mt, const ref Loc loc, const bool isCfi
         {
             printf("TypeTuple::defaultInit() '%s'\n", mt.toChars());
         }
-        auto exps = new Expressions(mt.arguments.dim);
-        for (size_t i = 0; i < mt.arguments.dim; i++)
+        auto exps = new Expressions(mt.arguments.length);
+        for (size_t i = 0; i < mt.arguments.length; i++)
         {
             Parameter p = (*mt.arguments)[i];
             assert(p.type);
@@ -4655,7 +4655,7 @@ private:
 Expression typeToExpressionHelper(TypeQualified t, Expression e, size_t i = 0)
 {
     //printf("toExpressionHelper(e = %s %s)\n", EXPtoString(e.op).ptr, e.toChars());
-    foreach (id; t.idents[i .. t.idents.dim])
+    foreach (id; t.idents[i .. t.idents.length])
     {
         //printf("\t[%d] e: '%s', id: '%s'\n", i, e.toChars(), id.toChars());
 
@@ -4770,7 +4770,7 @@ Type stripDefaultArgs(Type t)
                 if (ps)
                 {
                     // Replace params with a copy we can modify
-                    Parameters* nparams = new Parameters(parameters.dim);
+                    Parameters* nparams = new Parameters(parameters.length);
 
                     foreach (j, ref np; *nparams)
                     {
@@ -4898,7 +4898,7 @@ Expression getMaxMinValue(EnumDeclaration ed, const ref Loc loc, Identifier id)
     }
 
     bool first = true;
-    for (size_t i = 0; i < ed.members.dim; i++)
+    for (size_t i = 0; i < ed.members.length; i++)
     {
         EnumMember em = (*ed.members)[i].isEnumMember();
         if (!em)
diff --git a/gcc/d/typeinfo.cc b/gcc/d/typeinfo.cc
index 3577f669ed1..00fa2ba25a7 100644
--- a/gcc/d/typeinfo.cc
+++ b/gcc/d/typeinfo.cc
@@ -1064,17 +1064,6 @@ public:
       : null_pointer_node;
     this->layout_field (xhash);
 
-    if (sd->xhash)
-      {
-	TypeFunction *tf = sd->xhash->type->toTypeFunction ();
-	if (!tf->isnothrow () || tf->trust == TRUST::system)
-	  {
-	    warning (sd->xhash->loc, "toHash() must be declared as "
-		     "extern (D) size_t toHash() const nothrow @safe, "
-		     "not %s", tf->toChars ());
-	  }
-      }
-
     /* bool function(in void*, in void*) xopEquals;  */
     tree xeq = (sd->xeq) ? build_address (get_symbol_decl (sd->xeq))
       : null_pointer_node;
@@ -1410,7 +1399,7 @@ check_typeinfo_type (const Loc &loc, Scope *sc, Expression *expr)
     {
       /* Even when compiling without RTTI we should still be able to evaluate
 	 TypeInfo at compile-time, just not at run-time.  */
-      if (!sc || !(sc->flags & SCOPEctfe))
+      if (!sc || !(sc->flags & unsigned(SCOPE::ctfe)))
 	{
 	  static int warned = 0;
 
diff --git a/gcc/testsuite/gdc.test/compilable/nogc.d b/gcc/testsuite/gdc.test/compilable/nogc.d
index 6ce5094371f..88cf1229d4d 100644
--- a/gcc/testsuite/gdc.test/compilable/nogc.d
+++ b/gcc/testsuite/gdc.test/compilable/nogc.d
@@ -40,7 +40,8 @@ void foo_compiles() {}
     static assert(!__traits(compiles, delete p));
 
     int[int] aa;
-    static assert(!__traits(compiles, aa[0]));
+    static assert( __traits(compiles, aa[0]));
+    static assert(!__traits(compiles, (aa[0] = 10)));
 
     int[] a;
     static assert(!__traits(compiles, a.length = 1));
diff --git a/gcc/testsuite/gdc.test/compilable/test15712.d b/gcc/testsuite/gdc.test/compilable/test15712.d
new file mode 100644
index 00000000000..07321e5e038
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test15712.d
@@ -0,0 +1,12 @@
+// REQUIRED_ARGS: -unittest
+
+// https://issues.dlang.org/show_bug.cgi?id=15712
+// extern(C) attribute inside extern(C) unittest is incorrectly ignored
+
+extern(C):
+
+unittest
+{
+	extern(C) static void foo() {}
+	static assert(__traits(getLinkage, foo) == "C");
+}
diff --git a/gcc/testsuite/gdc.test/compilable/test23431.d b/gcc/testsuite/gdc.test/compilable/test23431.d
new file mode 100644
index 00000000000..8fafcb28a39
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test23431.d
@@ -0,0 +1,14 @@
+// https://issues.dlang.org/show_bug.cgi?id=23431
+// REQUIRED_ARGS: -lowmem
+void test23431()
+{
+    int a;
+    try
+    {
+        throw new Exception("test1");
+        a++;
+    }
+    finally
+    {
+    }
+}
diff --git a/gcc/testsuite/gdc.test/compilable/test23431_minimal.d b/gcc/testsuite/gdc.test/compilable/test23431_minimal.d
new file mode 100644
index 00000000000..0293f127286
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test23431_minimal.d
@@ -0,0 +1,28 @@
+// https://issues.dlang.org/show_bug.cgi?id=23431
+// REQUIRED_ARGS: -lowmem
+module object;
+
+alias string  = immutable(char)[];
+class Throwable { }
+class Exception : Throwable
+{
+    this(string )
+    {
+    }
+}
+
+class Error { }
+
+void test23431()
+{
+    int a;
+
+    try
+    {
+        throw new Exception("test1");
+        a++;
+    }
+    finally
+    {
+    }
+}
diff --git a/gcc/testsuite/gdc.test/compilable/test23433.d b/gcc/testsuite/gdc.test/compilable/test23433.d
new file mode 100644
index 00000000000..713267c0ecb
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test23433.d
@@ -0,0 +1,16 @@
+// https://issues.dlang.org/show_bug.cgi?id=23433
+module object;
+
+class Throwable { }
+class Exception : Throwable { this(immutable(char)[]) { } }
+
+void test23433()
+{
+    try
+    {
+        throw new Exception("ice");
+    }
+    finally
+    {
+    }
+}
diff --git a/gcc/testsuite/gdc.test/compilable/test23439.d b/gcc/testsuite/gdc.test/compilable/test23439.d
new file mode 100644
index 00000000000..eba292ce19f
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test23439.d
@@ -0,0 +1,8 @@
+// https://issues.dlang.org/show_bug.cgi?id=23439
+// PERMUTE_ARGS: -lowmem
+class C23439
+{
+    noreturn f23439;
+}
+
+__gshared ice23439 = new C23439();
diff --git a/gcc/testsuite/gdc.test/compilable/test23534.d b/gcc/testsuite/gdc.test/compilable/test23534.d
new file mode 100644
index 00000000000..f76a692b8b5
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test23534.d
@@ -0,0 +1,6 @@
+// https://issues.dlang.org/show_bug.cgi?id=23534
+
+enum E { a = 1, b = 2 }
+
+// `E.a` is not 0
+static assert(!__traits(isZeroInit, E));
diff --git a/gcc/testsuite/gdc.test/compilable/test4375.d b/gcc/testsuite/gdc.test/compilable/test4375.d
index 2a132fb109d..d7753cae546 100644
--- a/gcc/testsuite/gdc.test/compilable/test4375.d
+++ b/gcc/testsuite/gdc.test/compilable/test4375.d
@@ -202,7 +202,7 @@ label1:
             assert(78);
         else
             assert(79);
-        false; false
+        false;
     )
         if (true)
             assert(80);
diff --git a/gcc/testsuite/gdc.test/compilable/vgc2.d b/gcc/testsuite/gdc.test/compilable/vgc2.d
index c8959140da0..eeba627dcd6 100644
--- a/gcc/testsuite/gdc.test/compilable/vgc2.d
+++ b/gcc/testsuite/gdc.test/compilable/vgc2.d
@@ -93,8 +93,7 @@ void testAssocArray()
 /*
 TEST_OUTPUT:
 ---
-compilable/vgc2.d(102): vgc: indexing an associative array may cause a GC allocation
-compilable/vgc2.d(103): vgc: indexing an associative array may cause a GC allocation
+compilable/vgc2.d(101): vgc: assigning an associative array element may cause a GC allocation
 ---
 */
 void testIndex(int[int] aa)
diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag14818.d b/gcc/testsuite/gdc.test/fail_compilation/diag14818.d
index 660066af555..f9b535ab8d7 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/diag14818.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/diag14818.d
@@ -1,11 +1,17 @@
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/diag14818.d(34): Error: none of the overloads of `func` are callable using argument types `(string)`
-fail_compilation/diag14818.d(12):        Candidate is: `diag14818.foo(int _param_0)`
-fail_compilation/diag14818.d(13):                        `diag14818.bar(double _param_0)`
-fail_compilation/diag14818.d(35): Error: overload alias `diag14818.X` does not match any template declaration
-fail_compilation/diag14818.d(36): Error: overloadset `diag14818.M` does not match any template declaration
+fail_compilation/diag14818.d(40): Error: none of the overloads of `func` are callable using argument types `(string)`
+fail_compilation/diag14818.d(18):        Candidates are: `diag14818.foo(int _param_0)`
+fail_compilation/diag14818.d(19):                        `diag14818.bar(double _param_0)`
+fail_compilation/diag14818.d(41): Error: template instance `diag14818.X!string` does not match any template declaration
+fail_compilation/diag14818.d(41):        Candidates are:
+fail_compilation/diag14818.d(24):        Foo(T) if (is(T == int))
+fail_compilation/diag14818.d(25):        Bar(T) if (is(T == double))
+fail_compilation/diag14818.d(42): Error: template instance `diag14818.Y!string` does not match any template declaration
+fail_compilation/diag14818.d(42):        Candidates are:
+fail_compilation/diag14818.d(25):        Bar(T) if (is(T == double))
+fail_compilation/diag14818.d(24):        Foo(T) if (is(T == int))
 ---
 */
 
diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag8101.d b/gcc/testsuite/gdc.test/fail_compilation/diag8101.d
index 301472ca28a..9644fdd2242 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/diag8101.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/diag8101.d
@@ -2,7 +2,7 @@
 TEST_OUTPUT:
 ---
 fail_compilation/diag8101.d(57): Error: function `diag8101.f_0(int)` is not callable using argument types `()`
-fail_compilation/diag8101.d(57):        too few arguments, expected `1`, got `0`
+fail_compilation/diag8101.d(57):        too few arguments, expected 1, got 0
 fail_compilation/diag8101.d(58): Error: none of the overloads of `f_1` are callable using argument types `()`
 fail_compilation/diag8101.d(33):        Candidates are: `diag8101.f_1(int)`
 fail_compilation/diag8101.d(34):                        `diag8101.f_1(int, int)`
@@ -62,3 +62,6 @@ void main()
     t_1();
     t_2();
 }
+
+// ignored
+deprecated void f_2(char);
diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag_funclit.d b/gcc/testsuite/gdc.test/fail_compilation/diag_funclit.d
index 1279d7c2a2a..f00f91a1fc8 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/diag_funclit.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/diag_funclit.d
@@ -2,19 +2,19 @@
 TEST_OUTPUT:
 ---
 fail_compilation/diag_funclit.d(103): Error: function literal `__lambda1(x, y, z)` is not callable using argument types `()`
-fail_compilation/diag_funclit.d(103):        too few arguments, expected `3`, got `0`
+fail_compilation/diag_funclit.d(103):        too few arguments, expected 3, got 0
 fail_compilation/diag_funclit.d(106): Error: function literal `__lambda2(x, y, z)` is not callable using argument types `(int, string, int, int)`
-fail_compilation/diag_funclit.d(106):        too many arguments, expected `3`, got `4`
+fail_compilation/diag_funclit.d(106):        too many arguments, expected 3, got 4
 fail_compilation/diag_funclit.d(108): Error: function literal `__lambda3(x, y, string z = "Hello")` is not callable using argument types `(int, int, string, string)`
-fail_compilation/diag_funclit.d(108):        too many arguments, expected `3`, got `4`
+fail_compilation/diag_funclit.d(108):        too many arguments, expected 3, got 4
 fail_compilation/diag_funclit.d(110): Error: function literal `__lambda4(x, y, string z = "Hello")` is not callable using argument types `(int)`
-fail_compilation/diag_funclit.d(110):        too few arguments, expected `3`, got `1`
+fail_compilation/diag_funclit.d(110):        too few arguments, expected 3, got 1
 fail_compilation/diag_funclit.d(112): Error: function literal `__lambda5(x, y, z)` is not callable using argument types `(int)`
-fail_compilation/diag_funclit.d(112):        too few arguments, expected `3`, got `1`
+fail_compilation/diag_funclit.d(112):        too few arguments, expected 3, got 1
 fail_compilation/diag_funclit.d(115): Error: function literal `__lambda6(x, y, ...)` is not callable using argument types `(int)`
-fail_compilation/diag_funclit.d(115):        too few arguments, expected `2`, got `1`
+fail_compilation/diag_funclit.d(115):        too few arguments, expected 2, got 1
 fail_compilation/diag_funclit.d(117): Error: function literal `__lambda7(x, y, string z = "Hey", ...)` is not callable using argument types `(int)`
-fail_compilation/diag_funclit.d(117):        too few arguments, expected `3`, got `1`
+fail_compilation/diag_funclit.d(117):        too few arguments, expected 3, got 1
 ---
  */
 
diff --git a/gcc/testsuite/gdc.test/fail_compilation/diagin.d b/gcc/testsuite/gdc.test/fail_compilation/diagin.d
index 1418ced43a2..0d1f8f14fea 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/diagin.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/diagin.d
@@ -3,7 +3,7 @@ PERMUTE_ARGS: -preview=in
 TEST_OUTPUT:
 ---
 fail_compilation/diagin.d(14): Error: function `diagin.foo(in int)` is not callable using argument types `()`
-fail_compilation/diagin.d(14):        too few arguments, expected `1`, got `0`
+fail_compilation/diagin.d(14):        too few arguments, expected 1, got 0
 fail_compilation/diagin.d(16): Error: none of the overloads of template `diagin.foo1` are callable using argument types `!()(bool[])`
 fail_compilation/diagin.d(20):        Candidate is: `foo1(T)(in T v, string)`
 ---
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail12.d b/gcc/testsuite/gdc.test/fail_compilation/fail12.d
index d752d3822ca..7b082aea4a7 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail12.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail12.d
@@ -1,7 +1,9 @@
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/fail12.d(17): Error: function `fail12.main.Foo!(y).abc` at fail_compilation/fail12.d(9) conflicts with function `fail12.main.Foo!(y).abc` at fail_compilation/fail12.d(9)
+fail_compilation/fail12.d(19): Error: `abc` matches conflicting symbols:
+fail_compilation/fail12.d(11):        function `fail12.main.Foo!(y).abc`
+fail_compilation/fail12.d(11):        function `fail12.main.Foo!(y).abc`
 ---
 */
 template Foo(alias b)
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail15414.d b/gcc/testsuite/gdc.test/fail_compilation/fail15414.d
new file mode 100644
index 00000000000..1fb6e23aedb
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail15414.d
@@ -0,0 +1,21 @@
+// https://issues.dlang.org/show_bug.cgi?id=15414
+
+// REQUIRED_ARGS: -de
+
+/*
+TEST_OUTPUT:
+---
+fail_compilation/fail15414.d(20): Deprecation: `__traits(getAttributes)` may only be used for individual functions, not overload sets such as: `fun`
+fail_compilation/fail15414.d(20):        the result of `__traits(getOverloads)` may be used to select the desired function to extract attributes from
+---
+*/
+
+@("gigi")
+void fun() {}
+@("mimi")
+void fun(int) {}
+
+void main()
+{
+    auto t =  __traits(getAttributes, fun);
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail15616b.d b/gcc/testsuite/gdc.test/fail_compilation/fail15616b.d
index faad0f1dffc..4b209685ca4 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail15616b.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail15616b.d
@@ -22,7 +22,6 @@ fail_compilation/fail15616b.d(26):                        `foo(T)(T a)`
   `~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~`
 `  > is(T == char)
 `  `~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~`
-fail_compilation/fail15616b.d(44):        All possible candidates are marked as `deprecated` or `@disable`
   Tip: not satisfied constraints are marked with `>`
 ---
 */
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail1900.d b/gcc/testsuite/gdc.test/fail_compilation/fail1900.d
index fd0d6ac887f..edc463018db 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail1900.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail1900.d
@@ -30,7 +30,9 @@ void test1900a()
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/fail1900.d(42): Error: template `imports.fail1900b.Bar(short n)` at fail_compilation/imports/fail1900b.d(2) conflicts with template `imports.fail1900a.Bar(int n)` at fail_compilation/imports/fail1900a.d(2)
+fail_compilation/fail1900.d(44): Error: `Bar` matches conflicting symbols:
+fail_compilation/imports/fail1900b.d(2):        template `imports.fail1900b.Bar(short n)`
+fail_compilation/imports/fail1900a.d(2):        template `imports.fail1900a.Bar(int n)`
 ---
 */
 
@@ -45,7 +47,9 @@ void test1900b()
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/fail1900.d(66): Error: template `fail1900.Mix2b!().Baz(int x)` at fail_compilation/fail1900.d(58) conflicts with template `fail1900.Mix2a!().Baz(byte x)` at fail_compilation/fail1900.d(54)
+fail_compilation/fail1900.d(70): Error: `Baz` matches conflicting symbols:
+fail_compilation/fail1900.d(62):        template `fail1900.Mix2b!().Baz(int x)`
+fail_compilation/fail1900.d(58):        template `fail1900.Mix2a!().Baz(byte x)`
 ---
 */
 
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail22366.d b/gcc/testsuite/gdc.test/fail_compilation/fail22366.d
index 6960d5e41d8..675ba831ef6 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail22366.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail22366.d
@@ -1,15 +1,33 @@
-// REQUIRED_ARGS: -dip1000
-
 /*
+REQUIRED_ARGS: -preview=dip1000
 TEST_OUTPUT:
 ---
-fail_compilation/fail22366.d(13): Error: scope variable `x` may not be copied into allocated memory
+fail_compilation/fail22366.d(22): Error: scope variable `s` may not be copied into allocated memory
+fail_compilation/fail22366.d(25): Error: scope variable `s` may not be copied into allocated memory
+fail_compilation/fail22366.d(26): Error: scope variable `s` may not be copied into allocated memory
+fail_compilation/fail22366.d(27): Error: scope variable `s` may not be copied into allocated memory
+fail_compilation/fail22366.d(28): Error: scope variable `s` may not be copied into allocated memory
+fail_compilation/fail22366.d(31): Error: scope variable `s` may not be copied into allocated memory
+fail_compilation/fail22366.d(32): Error: scope variable `s` may not be copied into allocated memory
 ---
 */
 
-int* fun(scope int* x) @safe
+// Test escaping scope variables through AA keys / values
+// https://issues.dlang.org/show_bug.cgi?id=22366
+// https://issues.dlang.org/show_bug.cgi?id=23531
+
+void fun(scope string s) @safe
 {
-    int*[int] aa;
-    aa[0] = x; // should give an error
-    return aa[0];
+    int[string] aa;
+    aa[s] ^^= 3;
+
+    string[string] saa;
+    saa[""] = s;
+    saa[""] ~= s;
+    saa[s] = "";
+    saa[s] ~= "";
+
+    string[string][string] snaa;
+    snaa[s][""] = "";
+    snaa[""][s] = "";
 }
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail23439.d b/gcc/testsuite/gdc.test/fail_compilation/fail23439.d
new file mode 100644
index 00000000000..b070e581a4a
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail23439.d
@@ -0,0 +1,13 @@
+// https://issues.dlang.org/show_bug.cgi?id=23439
+// PERMUTE_ARGS: -lowmem
+/* TEST_OUTPUT:
+---
+fail_compilation/fail23439.d(13): Error: variable `fail23439.ice23439` is a thread-local class and cannot have a static initializer. Use `static this()` to initialize instead.
+---
+*/
+class C23439
+{
+    noreturn f23439;
+}
+
+static ice23439 = new C23439();
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail320.d b/gcc/testsuite/gdc.test/fail_compilation/fail320.d
index 24020b43b98..31dd0652687 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail320.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail320.d
@@ -2,10 +2,15 @@
 EXTRA_FILES: imports/fail320a.d imports/fail320b.d
 TEST_OUTPUT:
 ---
-fail_compilation/fail320.d(11): Error: no overload matches for `foo`
+fail_compilation/fail320.d(16): Error: no overload matches for `foo("")`
+fail_compilation/fail320.d(16):        Candidates are:
+fail_compilation/imports/fail320b.d(1):        foo(T)(string)
+fail_compilation/imports/fail320b.d(2):        foo(alias a)()
+fail_compilation/imports/fail320a.d(1):        foo(int)
+fail_compilation/imports/fail320a.d(2):        foo(bool)
 ---
 */
 
 import imports.fail320a;
 import imports.fail320b;
-void main() { foo(); }
+void main() { foo(""); }
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail54.d b/gcc/testsuite/gdc.test/fail_compilation/fail54.d
index e52c5336be6..e232523ed65 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail54.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail54.d
@@ -1,7 +1,12 @@
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/fail54.d(22): Error: incompatible types for `(0) == (Exception)`: cannot use `==` with types
+fail_compilation/fail54.d(27): Error: incompatible types for `(0) == (Exception)`: cannot use `==` with types
+fail_compilation/fail54.d(28): Error: incompatible types for `("") == (int)`: cannot use `==` with types
+fail_compilation/fail54.d(29): Error: incompatible types for `(true) == (int)`: cannot use `==` with types
+fail_compilation/fail54.d(29):        while evaluating: `static assert(true == (int))`
+fail_compilation/fail54.d(30): Error: incompatible types for `(true) == (int[string])`: cannot use `==` with types
+fail_compilation/fail54.d(30):        while evaluating: `static assert(true == (int[string]))`
 ---
 */
 
@@ -20,4 +25,7 @@ module dstress.nocompile.bug_mtype_507_C;
 void test()
 {
     0 == Exception;
+    "" == int;
+    static assert(is(int) == int);
+    static assert(is(int[string]) == int[string]);
 }
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail99.d b/gcc/testsuite/gdc.test/fail_compilation/fail99.d
index e4cba9530bf..a12fa3f4cc6 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail99.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail99.d
@@ -2,7 +2,7 @@
 TEST_OUTPUT:
 ---
 fail_compilation/fail99.d(13): Error: delegate `dg(int)` is not callable using argument types `()`
-fail_compilation/fail99.d(13):        too few arguments, expected `1`, got `0`
+fail_compilation/fail99.d(13):        too few arguments, expected 1, got 0
 ---
 */
 
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail_arrayop2.d b/gcc/testsuite/gdc.test/fail_compilation/fail_arrayop2.d
index e76a77950c7..c3c735ed552 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail_arrayop2.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail_arrayop2.d
@@ -327,6 +327,7 @@ fail_compilation/fail_arrayop2.d(342): Error: array operation `[1] * 6` without
 fail_compilation/fail_arrayop2.d(345): Error: array operation `[1] * 6` without destination memory not allowed
 fail_compilation/fail_arrayop2.d(348): Error: array operation `[1] * 6` without destination memory not allowed
 fail_compilation/fail_arrayop2.d(349): Error: array operation `[1] * 6` without destination memory not allowed
+fail_compilation/fail_arrayop2.d(350): Deprecation: `[1] * 6` has no effect
 fail_compilation/fail_arrayop2.d(350): Error: array operation `[1] * 6` without destination memory not allowed
 fail_compilation/fail_arrayop2.d(353): Error: array operation `[1] * 6` without destination memory not allowed
 fail_compilation/fail_arrayop2.d(356): Error: array operation `[1] * 6` without destination memory not allowed
@@ -336,8 +337,7 @@ fail_compilation/fail_arrayop2.d(367): Error: `"uvt"[] - '\x01'` cannot be inter
 ---
 */
 // Test all statements, which can take arrays as their operands.
-void test15407stmt()
-{
+void test15407stmt() {
     // ExpStatement - exp
     [1] * 6;
 
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail_pretty_errors.d b/gcc/testsuite/gdc.test/fail_compilation/fail_pretty_errors.d
index d25e8f77e05..e9533c04c69 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail_pretty_errors.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail_pretty_errors.d
@@ -2,16 +2,20 @@
 REQUIRED_ARGS: -verrors=context
 TEST_OUTPUT:
 ---
-fail_compilation/fail_pretty_errors.d(20): Error: undefined identifier `a`
+fail_compilation/fail_pretty_errors.d(24): Error: undefined identifier `a`
     a = 1;
     ^
-fail_compilation/fail_pretty_errors.d-mixin-25(25): Error: undefined identifier `b`
-fail_compilation/fail_pretty_errors.d(30): Error: cannot implicitly convert expression `5` of type `int` to `string`
+fail_compilation/fail_pretty_errors.d-mixin-29(29): Error: undefined identifier `b`
+fail_compilation/fail_pretty_errors.d(34): Error: cannot implicitly convert expression `5` of type `int` to `string`
     string x = 5;
                ^
-fail_compilation/fail_pretty_errors.d(35): Error: mixin `fail_pretty_errors.testMixin2.mixinTemplate!()` error instantiating
+fail_compilation/fail_pretty_errors.d(39): Error: mixin `fail_pretty_errors.testMixin2.mixinTemplate!()` error instantiating
     mixin mixinTemplate;
     ^
+fail_compilation/fail_pretty_errors.d(45): Error: invalid array operation `"" + ""` (possible missing [])
+    auto x = ""+"";
+             ^
+fail_compilation/fail_pretty_errors.d(45):        did you mean to concatenate (`"" ~ ""`) instead ?
 ---
 */
 
@@ -34,3 +38,9 @@ void testMixin2()
 {
     mixin mixinTemplate;
 }
+
+void f()
+{
+    // check supplemental error doesn't show context
+    auto x = ""+"";
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice10922.d b/gcc/testsuite/gdc.test/fail_compilation/ice10922.d
index f3a7a57a689..e76d4ac050d 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/ice10922.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/ice10922.d
@@ -2,7 +2,7 @@
 TEST_OUTPUT:
 ---
 fail_compilation/ice10922.d(10): Error: function `ice10922.__lambda4(in uint n)` is not callable using argument types `()`
-fail_compilation/ice10922.d(10):        too few arguments, expected `1`, got `0`
+fail_compilation/ice10922.d(10):        too few arguments, expected 1, got 0
 ---
 */
 
diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice13459.d b/gcc/testsuite/gdc.test/fail_compilation/ice13459.d
index 2c42dd32fdc..d34fc60db6a 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/ice13459.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/ice13459.d
@@ -3,7 +3,7 @@ TEST_OUTPUT:
 ---
 fail_compilation/ice13459.d(12): Error: undefined identifier `B`
 fail_compilation/ice13459.d(18): Error: none of the overloads of `opSlice` are callable using argument types `(int, int)`
-fail_compilation/ice13459.d(11):        Candidates are: `ice13459.A.opSlice()`
+fail_compilation/ice13459.d(11):        Candidate is: `ice13459.A.opSlice()`
 ---
 */
 struct A
diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice9540.d b/gcc/testsuite/gdc.test/fail_compilation/ice9540.d
index ce705078ac0..5276e83c722 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/ice9540.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/ice9540.d
@@ -2,7 +2,7 @@
 TEST_OUTPUT:
 ---
 fail_compilation/ice9540.d(35): Error: function `ice9540.A.test.AddFront!(this, f).AddFront.dg(int _param_0)` is not callable using argument types `()`
-fail_compilation/ice9540.d(35):        too few arguments, expected `1`, got `0`
+fail_compilation/ice9540.d(35):        too few arguments, expected 1, got 0
 fail_compilation/ice9540.d(26): Error: template instance `ice9540.A.test.AddFront!(this, f)` error instantiating
 ---
 */
diff --git a/gcc/testsuite/gdc.test/fail_compilation/imports/fail320a.d b/gcc/testsuite/gdc.test/fail_compilation/imports/fail320a.d
index 91972ed6546..d9e700d2e6a 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/imports/fail320a.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/imports/fail320a.d
@@ -1 +1,2 @@
 void foo(int) { }
+void foo(bool) { }
diff --git a/gcc/testsuite/gdc.test/fail_compilation/imports/fail320b.d b/gcc/testsuite/gdc.test/fail_compilation/imports/fail320b.d
index 9efc51c420c..b65463fddd0 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/imports/fail320b.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/imports/fail320b.d
@@ -1 +1,2 @@
-void foo(T)(){}
+void foo(T)(string){}
+void foo(alias a)(){}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/lexer23465.d b/gcc/testsuite/gdc.test/fail_compilation/lexer23465.d
new file mode 100644
index 00000000000..526b7704c88
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/lexer23465.d
@@ -0,0 +1,21 @@
+/*
+TEST_OUTPUT:
+---
+fail_compilation/lexer23465.d(19): Error: char 0x1f37a not allowed in identifier
+fail_compilation/lexer23465.d(19): Error: character 0x1f37a is not a valid token
+fail_compilation/lexer23465.d(20): Error: character '\' is not a valid token
+fail_compilation/lexer23465.d(21): Error: unterminated /+ +/ comment
+fail_compilation/lexer23465.d(22): Error: found `End of File` instead of array initializer
+fail_compilation/lexer23465.d(22): Error: semicolon needed to end declaration of `arr`, instead of `End of File`
+fail_compilation/lexer23465.d(17):        `arr` declared here
+---
+*/
+
+// https://issues.dlang.org/show_bug.cgi?id=23465
+// Invalid token error points to wrong line
+
+int[] arr = [
+	0,
+    x🍺,
+    3\,
+    5, /+
diff --git a/gcc/testsuite/gdc.test/fail_compilation/misc1.d b/gcc/testsuite/gdc.test/fail_compilation/misc1.d
index 9a319ebac28..21d02cdae44 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/misc1.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/misc1.d
@@ -3,6 +3,11 @@ TEST_OUTPUT:
 ---
 fail_compilation/misc1.d(108): Error: `5` has no effect
 fail_compilation/misc1.d(109): Error: `1 + 2` has no effect
+fail_compilation/misc1.d(115): Deprecation: `1 * 1` has no effect
+fail_compilation/misc1.d(116): Deprecation: `__lambda3` has no effect
+fail_compilation/misc1.d(122): Deprecation: `false` has no effect
+fail_compilation/misc1.d(125): Deprecation: `*sp++` has no effect
+fail_compilation/misc1.d(126): Deprecation: `j` has no effect
 ---
 */
 
@@ -18,3 +23,20 @@ void issue12490()
     5, hasSideEffect12490();
     1 + 2, hasSideEffect12490();
 }
+
+void issue23480()
+{
+    int j;
+    for({} j; 1*1) {}
+    for({j=2; int d = 3;} j+d<7; {j++; d++;}) {}
+    for (
+        if (true)        // (o_O)
+            assert(78);
+        else
+            assert(79);
+        false; false
+    ) {}
+    // unnecessary deref
+    for (ubyte* sp; 0; *sp++) {}
+    for (;; j) {}
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/nogc2.d b/gcc/testsuite/gdc.test/fail_compilation/nogc2.d
index 2a3ea8a99e0..9016dd9e969 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/nogc2.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/nogc2.d
@@ -92,8 +92,7 @@ fail_compilation/nogc2.d(87): Error: associative array literal in `@nogc` functi
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/nogc2.d(101): Error: indexing an associative array in `@nogc` function `nogc2.testIndex` may cause a GC allocation
-fail_compilation/nogc2.d(102): Error: indexing an associative array in `@nogc` function `nogc2.testIndex` may cause a GC allocation
+fail_compilation/nogc2.d(100): Error: assigning an associative array element in `@nogc` function `nogc2.testIndex` may cause a GC allocation
 ---
 */
 @nogc void testIndex(int[int] aa)
diff --git a/gcc/testsuite/gdc.test/fail_compilation/retscope.d b/gcc/testsuite/gdc.test/fail_compilation/retscope.d
index ece6a8cf62e..7bc5e96bef8 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/retscope.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/retscope.d
@@ -454,7 +454,7 @@ fail_compilation/retscope.d(1311): Error: scope variable `u2` assigned to `ek` w
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/retscope.d(1405): Error: reference to local variable `buf` assigned to non-scope parameter `__anonymous_param` calling `myprintf`
+fail_compilation/retscope.d(1405): Error: reference to local variable `buf` assigned to non-scope anonymous parameter calling `myprintf`
 ---
 */
 
@@ -472,7 +472,7 @@ fail_compilation/retscope.d(1405): Error: reference to local variable `buf` assi
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/retscope.d(1509): Error: reference to stack allocated value returned by `(*fp15)()` assigned to non-scope parameter `__anonymous_param`
+fail_compilation/retscope.d(1509): Error: reference to stack allocated value returned by `(*fp15)()` assigned to non-scope anonymous parameter
 ---
 */
 
diff --git a/gcc/testsuite/gdc.test/fail_compilation/retscope2.d b/gcc/testsuite/gdc.test/fail_compilation/retscope2.d
index 1cb76d6d5ae..829fb6a1970 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/retscope2.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/retscope2.d
@@ -86,8 +86,8 @@ fail_compilation/retscope2.d(504): Error: scope variable `c` may not be returned
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/retscope2.d(604): Error: scope variable `_param_0` assigned to non-scope parameter `__anonymous_param` calling `foo600`
-fail_compilation/retscope2.d(604): Error: scope variable `_param_1` assigned to non-scope parameter `__anonymous_param` calling `foo600`
+fail_compilation/retscope2.d(604): Error: scope variable `_param_0` assigned to non-scope anonymous parameter calling `foo600`
+fail_compilation/retscope2.d(604): Error: scope variable `_param_1` assigned to non-scope anonymous parameter calling `foo600`
 fail_compilation/retscope2.d(614): Error: template instance `retscope2.test600!(int*, int*)` error instantiating
 ---
 */
diff --git a/gcc/testsuite/gdc.test/fail_compilation/templateoverload.d b/gcc/testsuite/gdc.test/fail_compilation/templateoverload.d
new file mode 100644
index 00000000000..420e0b8b31f
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/templateoverload.d
@@ -0,0 +1,22 @@
+/*
+TEST_OUTPUT:
+---
+fail_compilation/templateoverload.d(17): Error: template instance `T!1` does not match any template declaration
+fail_compilation/templateoverload.d(17):        Candidates are:
+fail_compilation/templateoverload.d(14):        T(X)
+fail_compilation/templateoverload.d(15):        T()
+fail_compilation/templateoverload.d(22): Error: template instance `V!int` does not match any template declaration
+fail_compilation/templateoverload.d(22):        Candidates are:
+fail_compilation/templateoverload.d(19):        V(int i)
+fail_compilation/templateoverload.d(20):        V(T, alias a)
+---
+*/
+template T(X) {}
+template T() {}
+
+alias t = T!1;
+
+template V(int i) {}
+template V(T, alias a) {}
+
+alias v = V!int;
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test19646.d b/gcc/testsuite/gdc.test/fail_compilation/test19646.d
index ee0b042f7a7..c9d0e08f6e0 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/test19646.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/test19646.d
@@ -1,11 +1,17 @@
 /* TEST_OUTPUT:
 ---
 fail_compilation/test19646.d(11): Error: cast from `const(int)*` to `int*` not allowed in safe code
+fail_compilation/test19646.d(17): Error: `@safe` variable `z` cannot be initialized by calling `@system` function `f`
 ---
 https://issues.dlang.org/show_bug.cgi?id=19646
  */
 
 @safe:
-
 const x = 42;
 int* y = cast(int*)&x;
+
+@system:
+
+@system int* f() { return cast(int*) 0xDEADBEEF; };
+
+@safe int* z = f();
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test21008.d b/gcc/testsuite/gdc.test/fail_compilation/test21008.d
index 998cf1752d0..641c802c254 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/test21008.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/test21008.d
@@ -5,12 +5,12 @@ fail_compilation/test21008.d(110): Error: function `test21008.C.after` circular
 fail_compilation/test21008.d(117): Error: need `this` for `toString` of type `string()`
 fail_compilation/test21008.d(117): Error: need `this` for `toHash` of type `nothrow @trusted $?:32=uint|64=ulong$()`
 fail_compilation/test21008.d(117): Error: function `object.Object.opCmp(Object o)` is not callable using argument types `()`
-fail_compilation/test21008.d(117):        too few arguments, expected `1`, got `0`
+fail_compilation/test21008.d(117):        too few arguments, expected 1, got 0
 fail_compilation/test21008.d(117): Error: function `object.Object.opEquals(Object o)` is not callable using argument types `()`
-fail_compilation/test21008.d(117):        too few arguments, expected `1`, got `0`
+fail_compilation/test21008.d(117):        too few arguments, expected 1, got 0
 fail_compilation/test21008.d(117): Error: `Monitor` has no effect
 fail_compilation/test21008.d(117): Error: function `object.Object.factory(string classname)` is not callable using argument types `()`
-fail_compilation/test21008.d(117):        too few arguments, expected `1`, got `0`
+fail_compilation/test21008.d(117):        too few arguments, expected 1, got 0
 fail_compilation/test21008.d(105):        called from here: `handleMiddlewareAnnotation()`
 fail_compilation/test21008.d(108): Error: class `test21008.C` no size because of forward reference
 ---
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test21062.d b/gcc/testsuite/gdc.test/fail_compilation/test21062.d
new file mode 100644
index 00000000000..5ab53073733
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/test21062.d
@@ -0,0 +1,24 @@
+/*
+TEST_OUTPUT:
+---
+fail_compilation/test21062.d(16): Error: no identifier for declarator `bool`
+fail_compilation/test21062.d(16):        `synchronized` is a keyword, perhaps append `_` to make it an identifier
+fail_compilation/test21062.d(17): Error: no identifier for declarator `ubyte*`
+fail_compilation/test21062.d(17):        `out` is a keyword, perhaps append `_` to make it an identifier
+fail_compilation/test21062.d(21): Error: no identifier for declarator `uint`
+fail_compilation/test21062.d(21):        `in` is a keyword, perhaps append `_` to make it an identifier
+---
+*/
+
+// https://issues.dlang.org/show_bug.cgi?id=21062
+// Confusing error when using a keyword as an identifier for a declaration
+
+bool synchronized;
+ubyte* out;
+
+void main()
+{
+    foreach(uint in; [])
+    {
+    }
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test23491.d b/gcc/testsuite/gdc.test/fail_compilation/test23491.d
new file mode 100644
index 00000000000..b66d8a860d0
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/test23491.d
@@ -0,0 +1,19 @@
+/**
+REQUIRED_ARGS: -preview=dip1000
+TEST_OUTPUT:
+---
+fail_compilation/test23491.d(16): Error: reference to local variable `buffer` assigned to non-scope anonymous parameter
+fail_compilation/test23491.d(17): Error: reference to local variable `buffer` assigned to non-scope anonymous parameter calling `sinkF`
+fail_compilation/test23491.d(18): Error: reference to local variable `buffer` assigned to non-scope parameter `buf`
+---
+*/
+
+void sinkF(char[]) @safe;
+
+void toString(void delegate (char[]) @safe sink, void delegate(char[] buf) @safe sinkNamed) @safe
+{
+    char[20] buffer = void;
+    sink(buffer[]);
+	sinkF(buffer[]);
+	sinkNamed(buffer[]);
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test23536.d b/gcc/testsuite/gdc.test/fail_compilation/test23536.d
new file mode 100644
index 00000000000..fa1740bebad
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/test23536.d
@@ -0,0 +1,19 @@
+/* TEST_OUTPUT:
+---
+fail_compilation/test23536.d(104): Error: function `test23536.S.nonctor` cannot be a non-static member function for `pragma(crt_constructor)`
+fail_compilation/test23536.d(106): Error: function `test23536.S.nondtor` cannot be a non-static member function for `pragma(crt_destructor)`
+---
+*/
+
+// https://issues.dlang.org/show_bug.cgi?id=23536
+
+#line 100
+
+struct S
+{
+    int x;
+    extern (C) pragma(crt_constructor)        void nonctor() { } // should not compile
+    extern (C) pragma(crt_constructor) static void stactor() { } // should compile
+    extern (C) pragma(crt_destructor)         void nondtor() { } // should not compile
+    extern (C) pragma(crt_destructor)  static void stadtor() { } // should compile
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/throwexp.d b/gcc/testsuite/gdc.test/fail_compilation/throwexp.d
new file mode 100644
index 00000000000..b1216ce682f
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/throwexp.d
@@ -0,0 +1,12 @@
+/+ TEST_OUTPUT:
+---
+fail_compilation/throwexp.d(11): Error: to be thrown `ret()` must be non-null
+fail_compilation/throwexp.d(12): Error: to be thrown `null` must be non-null
+---
++/
+auto ret()
+{
+    return Exception.init;
+}
+enum y = throw ret();
+enum x = throw Exception.init;
diff --git a/gcc/testsuite/gdc.test/fail_compilation/warn14905.d b/gcc/testsuite/gdc.test/fail_compilation/warn14905.d
deleted file mode 100644
index 55520ba69c2..00000000000
--- a/gcc/testsuite/gdc.test/fail_compilation/warn14905.d
+++ /dev/null
@@ -1,23 +0,0 @@
-// REQUIRED_ARGS: -o- -w
-
-/*
-TEST_OUTPUT:
----
-fail_compilation/warn14905.d(16): Warning: statement is not reachable in template instance warn14905.fun!"a".fun
-fail_compilation/warn14905.d(16): Warning: statement is not reachable in template instance warn14905.fun!"b".fun
-Error: warnings are treated as errors
-       Use -wi if you wish to treat warnings only as informational.
----
-*/
-
-bool fun(string s)()
-{
-    return true;
-    return false;
-}
-
-void main()
-{
-    cast(void)fun!"a";
-    cast(void)fun!"b";
-}
diff --git a/gcc/testsuite/gdc.test/runnable/lexer.d b/gcc/testsuite/gdc.test/runnable/lexer.d
index 897514681d5..c6ca550011b 100644
--- a/gcc/testsuite/gdc.test/runnable/lexer.d
+++ b/gcc/testsuite/gdc.test/runnable/lexer.d
@@ -2,8 +2,8 @@
 /*
 TEST_OUTPUT:
 ---
-runnable/lexer.d(81): Deprecation: `version( <integer> )` is deprecated, use version identifiers instead
-runnable/lexer.d(82): Deprecation: `debug( <integer> )` is deprecated, use debug identifiers instead
+runnable/lexer.d(86): Deprecation: `version( <integer> )` is deprecated, use version identifiers instead
+runnable/lexer.d(87): Deprecation: `debug( <integer> )` is deprecated, use debug identifiers instead
 ---
 */
 
@@ -36,6 +36,11 @@ HERE";
     //writefln("'%s'", s);
     assert(s == "foo\n");
 
+    // https://issues.dlang.org/show_bug.cgi?id=19623
+    s = q"übel
+foo
+übel";
+    assert(s == "foo\n");
 
     s = q{ foo(xxx) };
     assert(s ==" foo(xxx) ");
diff --git a/gcc/testsuite/gdc.test/runnable/test21301.d b/gcc/testsuite/gdc.test/runnable/test21301.d
new file mode 100644
index 00000000000..073fd63c68a
--- /dev/null
+++ b/gcc/testsuite/gdc.test/runnable/test21301.d
@@ -0,0 +1,116 @@
+/* RUN_OUTPUT:
+---
+int   AAAA0000
+int   AAAA0001
+int   AAAA0002
+int   AAAA0003
+float FFFF0004
+float FFFF0005
+float FFFF0006
+float FFFF0007
+float FFFF0008
+float FFFF0009
+float FFFF0010
+float FFFF0011
+float FFFF0012
+float FFFF0013
+float FFFF0014
+float FFFF0015
+int   AAAA0016
+int   AAAA0017
+int   AAAA0018
+int   AAAA0019
+int   AAAA0020
+int   AAAA0021
+---
+ */
+
+// https://issues.dlang.org/show_bug.cgi?id=21301
+
+//extern (C)
+void func(
+    int p0, int[3] p1, float[3] p2, float p3, float p4, float p5, float p6, float p7,
+    float p8, float p9, float p10, float p11, int p12, int[2] p13, int p14, int p15, int p16
+) {
+    print(p0);
+
+    print(p1[0]);
+    print(p1[1]);
+    print(p1[2]);
+
+    print(p2[0]);
+    print(p2[1]);
+    print(p2[2]);
+
+    print(p3);
+    print(p4);
+    print(p5);
+    print(p6);
+    print(p7);
+    print(p8);
+    print(p9);
+    print(p10);
+    print(p11);
+    print(p12);
+    print(p13[0]);
+    print(p13[1]);
+    print(p14);
+    print(p15);
+    print(p16);
+}
+
+static if (0)
+{
+void print(int x);
+void print(float x);
+}
+else
+{
+import core.stdc.stdio;
+
+union U
+{
+    int[22] i = [
+        0xAAAA_0000,
+        0xAAAA_0001,
+        0xAAAA_0002,
+        0xAAAA_0003,
+        0xFFFF_0004,
+        0xFFFF_0005,
+        0xFFFF_0006,
+        0xFFFF_0007,
+        0xFFFF_0008,
+        0xFFFF_0009,
+        0xFFFF_0010,
+        0xFFFF_0011,
+        0xFFFF_0012,
+        0xFFFF_0013,
+        0xFFFF_0014,
+        0xFFFF_0015,
+        0xAAAA_0016,
+        0xAAAA_0017,
+        0xAAAA_0018,
+        0xAAAA_0019,
+        0xAAAA_0020,
+        0xAAAA_0021,
+    ];
+
+    float[22] f;
+}
+
+void print(int x) { printf("int   %08X\n", x); }
+void print(float x) { printf("float %08X\n", *(cast(int*) &x)); }
+
+int main()
+{
+    func(U.init.i[0],
+         [U.init.i[1], U.init.i[2], U.init.i[3]],
+         [U.init.f[4], U.init.f[5], U.init.f[6]],
+         U.init.f[7], U.init.f[8], U.init.f[9], U.init.f[10], U.init.f[11], U.init.f[12], U.init.f[13],
+         U.init.f[14], U.init.f[15], U.init.i[16],
+         [U.init.i[17], U.init.i[18]],
+         U.init.i[19], U.init.i[20], U.init.i[21]
+    );
+    return 0;
+}
+}
diff --git a/gcc/testsuite/gdc.test/runnable/test21506.d b/gcc/testsuite/gdc.test/runnable/test21506.d
new file mode 100644
index 00000000000..8f3394d6700
--- /dev/null
+++ b/gcc/testsuite/gdc.test/runnable/test21506.d
@@ -0,0 +1,40 @@
+/* RUN_OUTPUT:
+---
+value: -5
+value: -5
+---
+*/
+
+// https://issues.dlang.org/show_bug.cgi?id=21506
+
+import core.stdc.stdio;
+import core.stdc.stdarg;
+
+extern(C++)
+{
+
+void print(long a, va_list args){
+    vprintf("value: %d\n", args);
+}
+void proxy0(long a, long b, long c, long d, bool e, ...){
+    va_list ap;
+    va_start(ap, e);
+    print(a, ap);
+    va_end(ap);
+//  print(a, _argptr);
+}
+void proxy1(long d, bool e, ...){
+    va_list ap;
+    va_start(ap, e);
+    print(d, ap);
+    va_end(ap);
+//  print(d, _argptr);
+}
+
+}
+
+void main(){
+    int var = -5;
+    proxy0(1, 2, 3, 4, true, var);
+    proxy1(4, true, var);
+}
diff --git a/libphobos/libdruntime/MERGE b/libphobos/libdruntime/MERGE
index 2398875bce7..5ee6f624836 100644
--- a/libphobos/libdruntime/MERGE
+++ b/libphobos/libdruntime/MERGE
@@ -1,4 +1,4 @@
-e4f89195913be1dc638707b1abb24c4f3ae7e0bf
+c8ae4adb2eda515b09b326948e3a4aa9f489af45
 
 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/libdruntime/core/demangle.d b/libphobos/libdruntime/core/demangle.d
index c2d40322961..869ade64821 100644
--- a/libphobos/libdruntime/core/demangle.d
+++ b/libphobos/libdruntime/core/demangle.d
@@ -24,6 +24,11 @@ else version (WatchOS)
 debug(trace) import core.stdc.stdio : printf;
 debug(info) import core.stdc.stdio : printf;
 
+extern (C) alias CXX_DEMANGLER = char* function (const char* mangled_name,
+                                                char* output_buffer,
+                                                size_t* length,
+                                                int* status) nothrow pure @trusted;
+
 private struct NoHooks
 {
     // supported hooks
@@ -2115,19 +2120,22 @@ pure @safe:
 
 
 /**
- * Demangles D mangled names.  If it is not a D mangled name, it returns its
- * argument name.
+ * Demangles D/C++ mangled names.  If it is not a D/C++ mangled name, it
+ * returns its argument name.
  *
  * Params:
  *  buf = The string to demangle.
  *  dst = An optional destination buffer.
+ *  __cxa_demangle = optional C++ demangler
  *
  * Returns:
- *  The demangled name or the original string if the name is not a mangled D
- *  name.
+ *  The demangled name or the original string if the name is not a mangled
+ *  D/C++ name.
  */
-char[] demangle(return scope const(char)[] buf, return scope char[] dst = null ) nothrow pure @safe
+char[] demangle(return scope const(char)[] buf, return scope char[] dst = null, CXX_DEMANGLER __cxa_demangle = null) nothrow pure @safe
 {
+    if (buf.length > 2 && buf[0..2] == "_Z")
+        return demangleCXX(buf, __cxa_demangle, dst);
     auto d = Demangle!()(buf, dst);
     // fast path (avoiding throwing & catching exception) for obvious
     // non-D mangled names
@@ -2210,7 +2218,7 @@ char[] reencodeMangled(return scope const(char)[] mangled) nothrow pure @safe
             }
         }
 
-        bool parseLName(scope ref Remangle d) scope
+        bool parseLName(scope ref Remangle d) scope @trusted
         {
             flushPosition(d);
 
@@ -2261,7 +2269,7 @@ char[] reencodeMangled(return scope const(char)[] mangled) nothrow pure @safe
                 }
                 else
                 {
-                    idpos[id] = refpos;
+                    idpos[id] = refpos; //! scope variable id used as AA key, makes this function @trusted
                     result ~= d.buf[refpos .. d.pos];
                 }
             }
@@ -2706,8 +2714,10 @@ unittest
     {
         char[] buf = new char[i];
         auto ds = demangle(s, buf);
-        assert(ds == "pure nothrow @safe char[] core.demangle.demangle(scope return const(char)[], scope return char[])" ||
-               ds == "pure nothrow @safe char[] core.demangle.demangle(return scope const(char)[], return scope char[])");
+        assert(ds == "pure nothrow @safe char[] core.demangle.demangle(scope return const(char)[], scope return char[], extern (C) char* function(const(char*), char*, ulong*, int*) pure nothrow @trusted*)" ||
+               ds == "pure nothrow @safe char[] core.demangle.demangle(return scope const(char)[], return scope char[], extern (C) char* function(const(char*), char*, ulong*, int*) pure nothrow @trusted*)" ||
+               ds == "pure nothrow @safe char[] core.demangle.demangle(scope return const(char)[], scope return char[], extern (C) char* function(const(char*), char*, uint*, int*) pure nothrow @trusted*)" ||
+               ds == "pure nothrow @safe char[] core.demangle.demangle(return scope const(char)[], return scope char[], extern (C) char* function(const(char*), char*, uint*, int*) pure nothrow @trusted*)", ds);
     }
 }
 
@@ -2901,3 +2911,76 @@ private string toStringConsume (immutable ManglingFlagInfo[] infos, ref ushort b
     }
     return null;
 }
+
+private shared CXX_DEMANGLER __cxa_demangle;
+
+/**
+ * Returns:
+ *  a CXX_DEMANGLER if a C++ stdlib is loaded
+ */
+
+CXX_DEMANGLER getCXXDemangler() nothrow @trusted
+{
+    if (__cxa_demangle is null)
+    version (Posix)
+    {
+        import core.sys.posix.dlfcn : dlsym;
+        version (DragonFlyBSD) import core.sys.dragonflybsd.dlfcn : RTLD_DEFAULT;
+        version (FreeBSD) import core.sys.freebsd.dlfcn : RTLD_DEFAULT;
+        version (linux) import core.sys.linux.dlfcn : RTLD_DEFAULT;
+        version (NetBSD) import core.sys.netbsd.dlfcn : RTLD_DEFAULT;
+        version (OSX) import core.sys.darwin.dlfcn : RTLD_DEFAULT;
+        version (Solaris) import core.sys.solaris.dlfcn : RTLD_DEFAULT;
+
+        if (auto found = cast(CXX_DEMANGLER) dlsym(RTLD_DEFAULT, "__cxa_demangle"))
+            __cxa_demangle = found;
+    }
+
+    if (__cxa_demangle is null)
+        __cxa_demangle = (const char* mangled_name, char* output_buffer,
+                            size_t* length, int* status) nothrow pure @trusted {
+                                *status = -1;
+                                return null;
+                            };
+
+    return __cxa_demangle;
+}
+
+/**
+ * Demangles C++ mangled names.  If it is not a C++ mangled name, it
+ * returns its argument name.
+ *
+ * Params:
+ *  buf = The string to demangle.
+ *  __cxa_demangle = C++ demangler
+ *  dst = An optional destination buffer.
+ *
+ * Returns:
+ *  The demangled name or the original string if the name is not a mangled
+ *  C++ name.
+ */
+private char[] demangleCXX(return scope const(char)[] buf, CXX_DEMANGLER __cxa_demangle, return scope char[] dst = null,) nothrow pure @trusted
+{
+    char[] c_string = dst; // temporarily use dst buffer if possible
+    c_string.length = buf.length + 1;
+    c_string[0 .. buf.length] = buf[0 .. buf.length];
+    c_string[buf.length] = '\0';
+
+    int status;
+    size_t demangled_length;
+    auto demangled = __cxa_demangle(&c_string[0], null, &demangled_length, &status);
+    scope (exit) {
+        import core.memory;
+        pureFree(cast(void*) demangled);
+    }
+    if (status == 0)
+    {
+        dst.length = demangled_length;
+        dst[] = demangled[0 .. demangled_length];
+        return dst;
+    }
+
+    dst.length = buf.length;
+    dst[] = buf[];
+    return dst;
+}
diff --git a/libphobos/libdruntime/core/exception.d b/libphobos/libdruntime/core/exception.d
index a05a24cd19f..62179fec58b 100644
--- a/libphobos/libdruntime/core/exception.d
+++ b/libphobos/libdruntime/core/exception.d
@@ -608,7 +608,7 @@ extern (C) void onUnittestErrorMsg( string file, size_t line, string msg ) nothr
  * Throws:
  *  $(LREF RangeError).
  */
-extern (C) void onRangeError( string file = __FILE__, size_t line = __LINE__ ) @trusted pure nothrow @nogc
+extern (C) noreturn onRangeError( string file = __FILE__, size_t line = __LINE__ ) @trusted pure nothrow @nogc
 {
     throw staticError!RangeError(file, line, null);
 }
@@ -626,7 +626,7 @@ extern (C) void onRangeError( string file = __FILE__, size_t line = __LINE__ ) @
  * Throws:
  *  $(LREF ArraySliceError).
  */
-extern (C) void onArraySliceError( size_t lower = 0, size_t upper = 0, size_t length = 0,
+extern (C) noreturn onArraySliceError( size_t lower = 0, size_t upper = 0, size_t length = 0,
                               string file = __FILE__, size_t line = __LINE__ ) @trusted pure nothrow @nogc
 {
     throw staticError!ArraySliceError(lower, upper, length, file, line, null);
@@ -644,7 +644,7 @@ extern (C) void onArraySliceError( size_t lower = 0, size_t upper = 0, size_t le
  * Throws:
  *  $(LREF ArrayIndexError).
  */
-extern (C) void onArrayIndexError( size_t index = 0, size_t length = 0,
+extern (C) noreturn onArrayIndexError( size_t index = 0, size_t length = 0,
                               string file = __FILE__, size_t line = __LINE__ ) @trusted pure nothrow @nogc
 {
     throw staticError!ArrayIndexError(index, length, file, line, null);
@@ -662,7 +662,7 @@ extern (C) void onArrayIndexError( size_t index = 0, size_t length = 0,
  * Throws:
  *  $(LREF FinalizeError).
  */
-extern (C) void onFinalizeError( TypeInfo info, Throwable e, string file = __FILE__, size_t line = __LINE__ ) @trusted nothrow
+extern (C) noreturn onFinalizeError( TypeInfo info, Throwable e, string file = __FILE__, size_t line = __LINE__ ) @trusted nothrow
 {
     // This error is thrown during a garbage collection, so no allocation must occur while
     //  generating this object. So we use a preallocated instance
@@ -679,13 +679,13 @@ version (D_BetterC)
     // templates even for ordinary builds instead of providing them as an
     // extern(C) library.
 
-    void onOutOfMemoryError()(void* pretend_sideffect = null) @nogc nothrow pure @trusted
+    noreturn onOutOfMemoryError()(void* pretend_sideffect = null) @nogc nothrow pure @trusted
     {
         assert(0, "Memory allocation failed");
     }
     alias onOutOfMemoryErrorNoGC = onOutOfMemoryError;
 
-    void onInvalidMemoryOperationError()(void* pretend_sideffect = null) @nogc nothrow pure @trusted
+    noreturn onInvalidMemoryOperationError()(void* pretend_sideffect = null) @nogc nothrow pure @trusted
     {
         assert(0, "Invalid memory operation");
     }
@@ -699,14 +699,14 @@ else
      * Throws:
      *  $(LREF OutOfMemoryError).
      */
-    extern (C) void onOutOfMemoryError(void* pretend_sideffect = null) @trusted pure nothrow @nogc /* dmd @@@BUG11461@@@ */
+    extern (C) noreturn onOutOfMemoryError(void* pretend_sideffect = null) @trusted pure nothrow @nogc /* dmd @@@BUG11461@@@ */
     {
         // NOTE: Since an out of memory condition exists, no allocation must occur
         //       while generating this object.
         throw staticError!OutOfMemoryError();
     }
 
-    extern (C) void onOutOfMemoryErrorNoGC() @trusted nothrow @nogc
+    extern (C) noreturn onOutOfMemoryErrorNoGC() @trusted nothrow @nogc
     {
         // suppress stacktrace until they are @nogc
         throw staticError!OutOfMemoryError(false);
@@ -720,7 +720,7 @@ else
  * Throws:
  *  $(LREF InvalidMemoryOperationError).
  */
-extern (C) void onInvalidMemoryOperationError(void* pretend_sideffect = null) @trusted pure nothrow @nogc /* dmd @@@BUG11461@@@ */
+extern (C) noreturn onInvalidMemoryOperationError(void* pretend_sideffect = null) @trusted pure nothrow @nogc /* dmd @@@BUG11461@@@ */
 {
     // The same restriction applies as for onOutOfMemoryError. The GC is in an
     // undefined state, thus no allocation must occur while generating this object.
@@ -738,7 +738,7 @@ extern (C) void onInvalidMemoryOperationError(void* pretend_sideffect = null) @t
  * Throws:
  *  $(LREF ConfigurationError).
  */
-extern (C) void onForkError( string file = __FILE__, size_t line = __LINE__ ) @trusted pure nothrow @nogc
+extern (C) noreturn onForkError( string file = __FILE__, size_t line = __LINE__ ) @trusted pure nothrow @nogc
 {
     throw staticError!ForkError( file, line, null );
 }
@@ -755,7 +755,7 @@ extern (C) void onForkError( string file = __FILE__, size_t line = __LINE__ ) @t
  * Throws:
  *  $(LREF UnicodeException).
  */
-extern (C) void onUnicodeError( string msg, size_t idx, string file = __FILE__, size_t line = __LINE__ ) @safe pure
+extern (C) noreturn onUnicodeError( string msg, size_t idx, string file = __FILE__, size_t line = __LINE__ ) @safe pure
 {
     throw new UnicodeException( msg, idx, file, line );
 }
@@ -859,7 +859,7 @@ extern (C)
 private align(2 * size_t.sizeof) void[256] _store;
 
 // only Errors for now as those are rarely chained
-private T staticError(T, Args...)(auto ref Args args)
+package T staticError(T, Args...)(auto ref Args args)
     if (is(T : Error))
 {
     // pure hack, what we actually need is @noreturn and allow to call that in pure functions
diff --git a/libphobos/libdruntime/core/internal/gc/os.d b/libphobos/libdruntime/core/internal/gc/os.d
index 64f12033c95..38b60cbbcc4 100644
--- a/libphobos/libdruntime/core/internal/gc/os.d
+++ b/libphobos/libdruntime/core/internal/gc/os.d
@@ -70,10 +70,7 @@ else version (Posix)
         else if (errno ==  ECHILD)
             return ChildStatus.done; // someone called posix.syswait
         else if (waited_pid != pid || status != 0)
-        {
             onForkError();
-            return ChildStatus.error;
-        }
         return ChildStatus.done;
     }
 
diff --git a/libphobos/libdruntime/core/runtime.d b/libphobos/libdruntime/core/runtime.d
index 75e671cb34b..799e5252941 100644
--- a/libphobos/libdruntime/core/runtime.d
+++ b/libphobos/libdruntime/core/runtime.d
@@ -910,7 +910,7 @@ private:
         {
             fixbuf[0 .. symBeg] = buf[0 .. symBeg];
 
-            auto sym = demangle(buf[symBeg .. symEnd], fixbuf[symBeg .. $]);
+            auto sym = demangle(buf[symBeg .. symEnd], fixbuf[symBeg .. $], getCXXDemangler());
 
             if (sym.ptr !is fixbuf.ptr + symBeg)
             {
diff --git a/libphobos/libdruntime/core/sync/condition.d b/libphobos/libdruntime/core/sync/condition.d
index 674d78d60bb..ddd04ae0576 100644
--- a/libphobos/libdruntime/core/sync/condition.d
+++ b/libphobos/libdruntime/core/sync/condition.d
@@ -20,6 +20,9 @@ public import core.sync.exception;
 public import core.sync.mutex;
 public import core.time;
 
+import core.exception : AssertError, staticError;
+
+
 version (Windows)
 {
     import core.sync.semaphore;
@@ -51,7 +54,6 @@ else
 // void notifyAll();
 ////////////////////////////////////////////////////////////////////////////////
 
-
 /**
  * This class represents a condition variable as conceived by C.A.R. Hoare.  As
  * per Mesa type monitors however, "signal" has been replaced with "notify" to
@@ -74,19 +76,19 @@ class Condition
      * Throws:
      *  SyncError on error.
      */
-    this( Mutex m ) nothrow @safe
+    this( Mutex m ) nothrow @safe @nogc
     {
         this(m, true);
     }
 
     /// ditto
-    this( shared Mutex m ) shared nothrow @safe
+    this( shared Mutex m ) shared nothrow @safe @nogc
     {
         this(m, true);
     }
 
     //
-    private this(this Q, M)( M m, bool _unused_ ) nothrow @trusted
+    private this(this Q, M)( M m, bool _unused_ ) nothrow @trusted @nogc
         if ((is(Q == Condition) && is(M == Mutex)) ||
             (is(Q == shared Condition) && is(M == shared Mutex)))
     {
@@ -102,12 +104,12 @@ class Condition
             }
             m_blockLock = cast(HANDLE_TYPE) CreateSemaphoreA( null, 1, 1, null );
             if ( m_blockLock == m_blockLock.init )
-                throw new SyncError( "Unable to initialize condition" );
+                throw staticError!AssertError("Unable to initialize condition", __FILE__, __LINE__);
             scope(failure) CloseHandle( cast(void*) m_blockLock );
 
             m_blockQueue = cast(HANDLE_TYPE) CreateSemaphoreA( null, 0, int.max, null );
             if ( m_blockQueue == m_blockQueue.init )
-                throw new SyncError( "Unable to initialize condition" );
+                throw staticError!AssertError("Unable to initialize condition", __FILE__, __LINE__);
             scope(failure) CloseHandle( cast(void*) m_blockQueue );
 
             InitializeCriticalSection( cast(RTL_CRITICAL_SECTION*) &m_unblockLock );
@@ -123,29 +125,28 @@ class Condition
                     pthread_condattr_t attr = void;
                     int rc  = pthread_condattr_init( &attr );
                     if ( rc )
-                        throw new SyncError( "Unable to initialize condition" );
+                        throw staticError!AssertError("Unable to initialize condition", __FILE__, __LINE__);
                     rc = pthread_condattr_setclock( &attr, CLOCK_MONOTONIC );
                     if ( rc )
-                        throw new SyncError( "Unable to initialize condition" );
+                        throw staticError!AssertError("Unable to initialize condition", __FILE__, __LINE__);
                     rc = pthread_cond_init( cast(pthread_cond_t*) &m_hndl, &attr );
                     if ( rc )
-                        throw new SyncError( "Unable to initialize condition" );
+                        throw staticError!AssertError("Unable to initialize condition", __FILE__, __LINE__);
                     rc = pthread_condattr_destroy( &attr );
                     if ( rc )
-                        throw new SyncError( "Unable to initialize condition" );
+                        throw staticError!AssertError("Unable to initialize condition", __FILE__, __LINE__);
                 } ();
             }
             else
             {
                 int rc = pthread_cond_init( cast(pthread_cond_t*) &m_hndl, null );
                 if ( rc )
-                    throw new SyncError( "Unable to initialize condition" );
+                    throw staticError!AssertError("Unable to initialize condition", __FILE__, __LINE__);
             }
         }
     }
 
-
-    ~this()
+    ~this() @nogc
     {
         version (Windows)
         {
@@ -231,7 +232,7 @@ class Condition
         {
             int rc = pthread_cond_wait( cast(pthread_cond_t*) &m_hndl, (cast(Mutex) m_assocMutex).handleAddr() );
             if ( rc )
-                throw new SyncError( "Unable to wait for condition" );
+                throw staticError!AssertError("Unable to wait for condition", __FILE__, __LINE__);
         }
     }
 
@@ -296,7 +297,7 @@ class Condition
                 return true;
             if ( rc == ETIMEDOUT )
                 return false;
-            throw new SyncError( "Unable to wait for condition" );
+            throw staticError!AssertError("Unable to wait for condition", __FILE__, __LINE__);
         }
     }
 
@@ -344,7 +345,7 @@ class Condition
                 rc = pthread_cond_signal( cast(pthread_cond_t*) &m_hndl );
             } while ( rc == EAGAIN );
             if ( rc )
-                throw new SyncError( "Unable to notify condition" );
+                throw staticError!AssertError("Unable to notify condition", __FILE__, __LINE__);
         }
     }
 
@@ -392,7 +393,7 @@ class Condition
                 rc = pthread_cond_broadcast( cast(pthread_cond_t*) &m_hndl );
             } while ( rc == EAGAIN );
             if ( rc )
-                throw new SyncError( "Unable to notify condition" );
+                throw staticError!AssertError("Unable to notify condition", __FILE__, __LINE__);
         }
     }
 
diff --git a/libphobos/libdruntime/core/sync/mutex.d b/libphobos/libdruntime/core/sync/mutex.d
index b848a147460..e7380c46725 100644
--- a/libphobos/libdruntime/core/sync/mutex.d
+++ b/libphobos/libdruntime/core/sync/mutex.d
@@ -292,7 +292,7 @@ private:
 package:
     version (Posix)
     {
-        pthread_mutex_t* handleAddr()
+        pthread_mutex_t* handleAddr() @nogc
         {
             return &m_hndl;
         }
diff --git a/libphobos/libdruntime/core/sys/posix/sys/wait.d b/libphobos/libdruntime/core/sys/posix/sys/wait.d
index 766a4e0b6aa..145149be528 100644
--- a/libphobos/libdruntime/core/sys/posix/sys/wait.d
+++ b/libphobos/libdruntime/core/sys/posix/sys/wait.d
@@ -451,6 +451,7 @@ else version (NetBSD)
 }
 else version (OpenBSD)
 {
+    int waitid(idtype_t, id_t, siginfo_t*, int);
 }
 else version (DragonFlyBSD)
 {
diff --git a/libphobos/libdruntime/core/sys/windows/winsock2.d b/libphobos/libdruntime/core/sys/windows/winsock2.d
index 522564516a9..b036df39dfe 100644
--- a/libphobos/libdruntime/core/sys/windows/winsock2.d
+++ b/libphobos/libdruntime/core/sys/windows/winsock2.d
@@ -63,11 +63,11 @@ int getsockopt(SOCKET s, int level, int optname, void* optval, socklen_t* optlen
 int setsockopt(SOCKET s, int level, int optname, const(void)* optval, socklen_t optlen);
 uint inet_addr(const char* cp);
 int select(int nfds, fd_set* readfds, fd_set* writefds, fd_set* errorfds, const(timeval)* timeout);
-@trusted char* inet_ntoa(in_addr ina);
+char* inet_ntoa(in_addr ina);
 hostent* gethostbyname(const char* name);
 hostent* gethostbyaddr(const(void)* addr, int len, int type);
 protoent* getprotobyname(const char* name);
-@trusted protoent* getprotobynumber(int number);
+protoent* getprotobynumber(int number);
 servent* getservbyname(const char* name, const char* proto);
 servent* getservbyport(int port, const char* proto);
 }
diff --git a/libphobos/src/MERGE b/libphobos/src/MERGE
index d02f72d5b4f..09da6a800bd 100644
--- a/libphobos/src/MERGE
+++ b/libphobos/src/MERGE
@@ -1,4 +1,4 @@
-3ad507b5125573c5b47736a0913105bfb1249746
+792c8b7c1d5957767e138f78d04bf175d4b92f10
 
 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/algorithm/mutation.d b/libphobos/src/std/algorithm/mutation.d
index 839183deea0..9b1d9207b9a 100644
--- a/libphobos/src/std/algorithm/mutation.d
+++ b/libphobos/src/std/algorithm/mutation.d
@@ -573,7 +573,7 @@ $(LINK2 http://en.cppreference.com/w/cpp/algorithm/copy_backward, STL's `copy_ba
 Assigns `value` to each element of input range `range`.
 
 Alternatively, instead of using a single `value` to fill the `range`,
-a `filter` $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives)
+a `filler` $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives)
 can be provided. The length of `filler` and `range` do not need to match, but
 `filler` must not be empty.
 
diff --git a/libphobos/src/std/algorithm/sorting.d b/libphobos/src/std/algorithm/sorting.d
index 4fc7ee9ac4c..ddb80b8fc68 100644
--- a/libphobos/src/std/algorithm/sorting.d
+++ b/libphobos/src/std/algorithm/sorting.d
@@ -3946,7 +3946,7 @@ if (isRandomAccessRange!(Range1) && hasLength!Range1 &&
     {
         foreach (T2; ReferenceRanges)
         {
-            import std.array;
+            import std.array : array;
 
             T1 A;
             T2 B;
diff --git a/libphobos/src/std/array.d b/libphobos/src/std/array.d
index 3e882003f38..daa103a9a42 100644
--- a/libphobos/src/std/array.d
+++ b/libphobos/src/std/array.d
@@ -169,8 +169,8 @@ if (isIterable!Range && !isAutodecodableString!Range && !isInfinite!Range)
 }
 
 /// ditto
-ForeachType!(PointerTarget!Range)[] array(Range)(Range r)
-if (isPointer!Range && isIterable!(PointerTarget!Range) && !isAutodecodableString!Range && !isInfinite!Range)
+ForeachType!(typeof((*Range).init))[] array(Range)(Range r)
+if (is(Range : U*, U) && isIterable!U && !isAutodecodableString!Range && !isInfinite!Range)
 {
     return array(*r);
 }
@@ -3416,7 +3416,8 @@ do
 Implements an output range that appends data to an array. This is
 recommended over $(D array ~= data) when appending many elements because it is more
 efficient. `Appender` maintains its own array metadata locally, so it can avoid
-global locking for each append where $(LREF capacity) is non-zero.
+the $(DDSUBLINK spec/arrays, capacity-reserve, performance hit of looking up slice `capacity`)
+for each append.
 
 Params:
     A = the array type to simulate.
@@ -3587,7 +3588,7 @@ if (isDynamicArray!A)
     private template canPutItem(U)
     {
         enum bool canPutItem =
-            isImplicitlyConvertible!(Unqual!U, Unqual!T) ||
+            is(Unqual!U : Unqual!T) ||
             isSomeChar!T && isSomeChar!U;
     }
     private template canPutConstRange(Range)
diff --git a/libphobos/src/std/base64.d b/libphobos/src/std/base64.d
index 2f7213b737b..0fc92ac2b01 100644
--- a/libphobos/src/std/base64.d
+++ b/libphobos/src/std/base64.d
@@ -639,7 +639,7 @@ template Base64Impl(char Map62th, char Map63th, char Padding = '=')
          */
         void popFront()
         {
-            enforce(!empty, new Base64Exception("Cannot call popFront on Encoder with no data remaining"));
+            assert(!empty, "Cannot call popFront on Encoder with no data remaining");
 
             range_.popFront();
 
@@ -757,7 +757,7 @@ template Base64Impl(char Map62th, char Map63th, char Padding = '=')
          */
         void popFront()
         {
-            enforce(!empty, new Base64Exception("Cannot call popFront on Encoder with no data remaining"));
+            assert(!empty, "Cannot call popFront on Encoder with no data remaining");
 
             static if (Padding != NoPadding)
                 if (padding)
@@ -1414,7 +1414,7 @@ template Base64Impl(char Map62th, char Map63th, char Padding = '=')
          */
         void popFront()
         {
-            enforce(!empty, new Base64Exception("Cannot call popFront on Decoder with no data remaining."));
+            assert(!empty, "Cannot call popFront on Decoder with no data remaining.");
 
             range_.popFront();
 
diff --git a/libphobos/src/std/bitmanip.d b/libphobos/src/std/bitmanip.d
index f131257f777..559f8da5f3f 100644
--- a/libphobos/src/std/bitmanip.d
+++ b/libphobos/src/std/bitmanip.d
@@ -1418,9 +1418,9 @@ public:
     /**
       Flips a single bit, specified by `pos`
      */
-    void flip(size_t i) @nogc pure nothrow
+    void flip(size_t pos) @nogc pure nothrow
     {
-        bt(_ptr, i) ? btr(_ptr, i) : bts(_ptr, i);
+        bt(_ptr, pos) ? btr(_ptr, pos) : bts(_ptr, pos);
     }
 
     ///
diff --git a/libphobos/src/std/checkedint.d b/libphobos/src/std/checkedint.d
index 635c4207fcd..79597e8dacc 100644
--- a/libphobos/src/std/checkedint.d
+++ b/libphobos/src/std/checkedint.d
@@ -630,36 +630,36 @@ if (isIntegral!T || is(T == Checked!(U, H), U, H))
         import core.atomic : atomicLoad, MemoryOrder;
         static if (is(typeof(this.payload.atomicLoad!(MemoryOrder.acq)) P))
         {
-            auto payload = __ctfe ? cast(P) this.payload
+            auto localPayload = __ctfe ? cast(P) this.payload
                                   : this.payload.atomicLoad!(MemoryOrder.acq);
         }
         else
         {
-            alias payload = this.payload;
+            alias localPayload = this.payload;
         }
 
         static if (hasMember!(Hook, "hookToHash"))
         {
-            return hook.hookToHash(payload);
+            return hook.hookToHash(localPayload);
         }
         else static if (stateSize!Hook > 0)
         {
-            static if (hasMember!(typeof(payload), "toHash"))
+            static if (hasMember!(typeof(localPayload), "toHash"))
             {
-                return payload.toHash() ^ hashOf(hook);
+                return localPayload.toHash() ^ hashOf(hook);
             }
             else
             {
-                return hashOf(payload) ^ hashOf(hook);
+                return hashOf(localPayload) ^ hashOf(hook);
             }
         }
-        else static if (hasMember!(typeof(payload), "toHash"))
+        else static if (hasMember!(typeof(localPayload), "toHash"))
         {
-            return payload.toHash();
+            return localPayload.toHash();
         }
         else
         {
-            return .hashOf(payload);
+            return .hashOf(localPayload);
         }
     }
 
diff --git a/libphobos/src/std/concurrency.d b/libphobos/src/std/concurrency.d
index bc53236b9b7..323926a6aae 100644
--- a/libphobos/src/std/concurrency.d
+++ b/libphobos/src/std/concurrency.d
@@ -480,7 +480,7 @@ private template isSpawnable(F, T...)
             enum isParamsImplicitlyConvertible = false;
         else static if (param1.length == i)
             enum isParamsImplicitlyConvertible = true;
-        else static if (isImplicitlyConvertible!(param2[i], param1[i]))
+        else static if (is(param2[i] : param1[i]))
             enum isParamsImplicitlyConvertible = isParamsImplicitlyConvertible!(F1,
                     F2, i + 1);
         else
@@ -2129,7 +2129,7 @@ private
 
             static assert(T.length, "T must not be empty");
 
-            static if (isImplicitlyConvertible!(T[0], Duration))
+            static if (is(T[0] : Duration))
             {
                 alias Ops = AliasSeq!(T[1 .. $]);
                 alias ops = vals[1 .. $];
diff --git a/libphobos/src/std/container/array.d b/libphobos/src/std/container/array.d
index ecc45996925..f5efe6d1f2a 100644
--- a/libphobos/src/std/container/array.d
+++ b/libphobos/src/std/container/array.d
@@ -34,7 +34,7 @@ pure @system unittest
         float[] a0;
         {
             import std.range : iota;
-            import std.array;
+            import std.array : array;
             import std.algorithm.iteration : map;
             a0 = iota (0, n).map!(i => i * 1.1f).array;
         }
@@ -991,7 +991,7 @@ if (!is(immutable T == immutable bool))
      */
     void removeBack()
     {
-        enforce(!empty);
+        assert(!empty);
         static if (hasElaborateDestructor!T)
             .destroy(_data._payload[$ - 1]);
 
@@ -1812,49 +1812,49 @@ if (is(immutable T == immutable bool))
         /// Ditto
         @property T front()
         {
-            enforce(!empty, "Attempting to access the front of an empty Array");
+            assert(!empty, "Attempting to access the front of an empty Array");
             return _outer[_a];
         }
         /// Ditto
         @property void front(bool value)
         {
-            enforce(!empty, "Attempting to set the front of an empty Array");
+            assert(!empty, "Attempting to set the front of an empty Array");
             _outer[_a] = value;
         }
         /// Ditto
         T moveFront()
         {
-            enforce(!empty, "Attempting to move the front of an empty Array");
+            assert(!empty, "Attempting to move the front of an empty Array");
             return _outer.moveAt(_a);
         }
         /// Ditto
         void popFront()
         {
-            enforce(!empty, "Attempting to popFront an empty Array");
+            assert(!empty, "Attempting to popFront an empty Array");
             ++_a;
         }
         /// Ditto
         @property T back()
         {
-            enforce(!empty, "Attempting to access the back of an empty Array");
+            assert(!empty, "Attempting to access the back of an empty Array");
             return _outer[_b - 1];
         }
         /// Ditto
         @property void back(bool value)
         {
-            enforce(!empty, "Attempting to set the back of an empty Array");
+            assert(!empty, "Attempting to set the back of an empty Array");
             _outer[_b - 1] = value;
         }
         /// Ditto
         T moveBack()
         {
-            enforce(!empty, "Attempting to move the back of an empty Array");
+            assert(!empty, "Attempting to move the back of an empty Array");
             return _outer.moveAt(_b - 1);
         }
         /// Ditto
         void popBack()
         {
-            enforce(!empty, "Attempting to popBack an empty Array");
+            assert(!empty, "Attempting to popBack an empty Array");
             --_b;
         }
         /// Ditto
@@ -2029,14 +2029,14 @@ if (is(immutable T == immutable bool))
      */
     @property bool front()
     {
-        enforce(!empty);
+        assert(!empty);
         return data.ptr[0] & 1;
     }
 
     /// Ditto
     @property void front(bool value)
     {
-        enforce(!empty);
+        assert(!empty);
         if (value) data.ptr[0] |= 1;
         else data.ptr[0] &= ~cast(size_t) 1;
     }
@@ -2052,14 +2052,14 @@ if (is(immutable T == immutable bool))
      */
     @property bool back()
     {
-        enforce(!empty);
+        assert(!empty);
         return cast(bool)(data.back & (cast(size_t) 1 << ((_store._length - 1) % bitsPerWord)));
     }
 
     /// Ditto
     @property void back(bool value)
     {
-        enforce(!empty);
+        assert(!empty);
         if (value)
         {
             data.back |= (cast(size_t) 1 << ((_store._length - 1) % bitsPerWord));
diff --git a/libphobos/src/std/container/binaryheap.d b/libphobos/src/std/container/binaryheap.d
index 723630c89e2..7ff14fc3bad 100644
--- a/libphobos/src/std/container/binaryheap.d
+++ b/libphobos/src/std/container/binaryheap.d
@@ -249,7 +249,7 @@ according to `less`.
      */
     @property ElementType!Store front()
     {
-        enforce(!empty, "Cannot call front on an empty heap.");
+        assert(!empty, "Cannot call front on an empty heap.");
         return _store.front;
     }
 
@@ -317,7 +317,7 @@ Removes the largest element from the heap.
      */
     void removeFront()
     {
-        enforce(!empty, "Cannot call removeFront on an empty heap.");
+        assert(!empty, "Cannot call removeFront on an empty heap.");
         if (_length > 1)
         {
             auto t1 = _store[].moveFront();
diff --git a/libphobos/src/std/conv.d b/libphobos/src/std/conv.d
index 0f660658920..d1b64212e39 100644
--- a/libphobos/src/std/conv.d
+++ b/libphobos/src/std/conv.d
@@ -162,12 +162,12 @@ private
 
     template isEnumStrToStr(S, T)
     {
-        enum isEnumStrToStr = isImplicitlyConvertible!(S, T) &&
+        enum isEnumStrToStr = is(S : T) &&
                               is(S == enum) && isExactSomeString!T;
     }
     template isNullToStr(S, T)
     {
-        enum isNullToStr = isImplicitlyConvertible!(S, T) &&
+        enum isNullToStr = is(S : T) &&
                            (is(immutable S == immutable typeof(null))) && isExactSomeString!T;
     }
 }
@@ -542,7 +542,7 @@ If the source type is implicitly convertible to the target type, $(D
 to) simply performs the implicit conversion.
  */
 private T toImpl(T, S)(S value)
-if (isImplicitlyConvertible!(S, T) &&
+if (is(S : T) &&
     !isEnumStrToStr!(S, T) && !isNullToStr!(S, T))
 {
     template isSignedInt(T)
@@ -699,7 +699,7 @@ if (isStaticArray!S)
 When source type supports member template function opCast, it is used.
 */
 private T toImpl(T, S)(S value)
-if (!isImplicitlyConvertible!(S, T) &&
+if (!is(S : T) &&
     is(typeof(S.init.opCast!T()) : T) &&
     !isExactSomeString!T &&
     !is(typeof(T(value))))
@@ -750,7 +750,7 @@ $(UL $(LI If target type is struct, `T(value)` is used.)
      $(LI If target type is class, $(D new T(value)) is used.))
 */
 private T toImpl(T, S)(S value)
-if (!isImplicitlyConvertible!(S, T) &&
+if (!is(S : T) &&
     is(T == struct) && is(typeof(T(value))))
 {
     return T(value);
@@ -799,7 +799,7 @@ if (!isImplicitlyConvertible!(S, T) &&
 
 /// ditto
 private T toImpl(T, S)(S value)
-if (!isImplicitlyConvertible!(S, T) &&
+if (!is(S : T) &&
     is(T == class) && is(typeof(new T(value))))
 {
     return new T(value);
@@ -872,7 +872,7 @@ Object-to-object conversions by dynamic casting throw exception when the source
 non-null and the target is null.
  */
 private T toImpl(T, S)(S value)
-if (!isImplicitlyConvertible!(S, T) &&
+if (!is(S : T) &&
     (is(S == class) || is(S == interface)) && !is(typeof(value.opCast!T()) : T) &&
     (is(T == class) || is(T == interface)) && !is(typeof(new T(value))))
 {
@@ -957,7 +957,7 @@ if (!isImplicitlyConvertible!(S, T) &&
         alias tgtmod = AddModifier!m2;
 
         // Compile time convertible equals to modifier convertible.
-        static if (isImplicitlyConvertible!(srcmod!Object, tgtmod!Object))
+        static if (is(srcmod!Object : tgtmod!Object))
         {
             // Test runtime conversions: class to class, class to interface,
             // interface to class, and interface to interface
@@ -993,7 +993,7 @@ if (!isImplicitlyConvertible!(S, T) &&
 Handles type _to string conversions
 */
 private T toImpl(T, S)(S value)
-if (!(isImplicitlyConvertible!(S, T) &&
+if (!(is(S : T) &&
     !isEnumStrToStr!(S, T) && !isNullToStr!(S, T)) &&
     !isInfinite!S && isExactSomeString!T)
 {
@@ -1138,7 +1138,7 @@ if (!(isImplicitlyConvertible!(S, T) &&
     To string conversion for non copy-able structs
  */
 private T toImpl(T, S)(ref S value)
-if (!(isImplicitlyConvertible!(S, T) &&
+if (!(is(S : T) &&
     !isEnumStrToStr!(S, T) && !isNullToStr!(S, T)) &&
     !isInfinite!S && isExactSomeString!T && !isCopyable!S && !isStaticArray!S)
 {
@@ -1528,7 +1528,7 @@ Narrowing numeric-numeric conversions throw when the value does not
 fit in the narrower type.
  */
 private T toImpl(T, S)(S value)
-if (!isImplicitlyConvertible!(S, T) &&
+if (!is(S : T) &&
     (isNumeric!S || isSomeChar!S || isBoolean!S) &&
     (isNumeric!T || isSomeChar!T || isBoolean!T) && !is(T == enum))
 {
@@ -1643,7 +1643,7 @@ Array-to-array conversion (except when target is a string type)
 converts each element in turn by using `to`.
  */
 private T toImpl(T, S)(scope S value)
-if (!isImplicitlyConvertible!(S, T) &&
+if (!is(S : T) &&
     !isSomeString!S && isDynamicArray!S &&
     !isExactSomeString!T && isArray!T)
 {
@@ -1725,7 +1725,7 @@ Associative array to associative array conversion converts each key
 and each value in turn.
  */
 private T toImpl(T, S)(S value)
-if (!isImplicitlyConvertible!(S, T) && isAssociativeArray!S &&
+if (!is(S : T) && isAssociativeArray!S &&
     isAssociativeArray!T && !is(T == enum))
 {
     /* This code is potentially unsafe.
diff --git a/libphobos/src/std/datetime/systime.d b/libphobos/src/std/datetime/systime.d
index e80f1225155..6898934f809 100644
--- a/libphobos/src/std/datetime/systime.d
+++ b/libphobos/src/std/datetime/systime.d
@@ -10095,7 +10095,7 @@ else version (Windows)
 
         static void testScope(scope ref SysTime st) @safe
         {
-            auto result = SysTimeToSYSTEMTIME(st);
+            auto localResult = SysTimeToSYSTEMTIME(st);
         }
     }
 
@@ -10178,7 +10178,7 @@ else version (Windows)
 
         static void testScope(scope ref SysTime st) @safe
         {
-            auto result = SysTimeToFILETIME(st);
+            auto local_result = SysTimeToFILETIME(st);
         }
     }
 }
diff --git a/libphobos/src/std/digest/hmac.d b/libphobos/src/std/digest/hmac.d
index 6864fc37c4b..6688ba7451a 100644
--- a/libphobos/src/std/digest/hmac.d
+++ b/libphobos/src/std/digest/hmac.d
@@ -202,14 +202,14 @@ if (hashBlockSize % 8 == 0)
         import std.string : representation;
         string data1 = "Hello, world", data2 = "Hola mundo";
         auto hmac = HMAC!SHA1("My s3cR3T keY".representation);
-        auto digest = hmac.put(data1.representation)
+        auto testDigest = hmac.put(data1.representation)
                           .put(data2.representation)
                           .finish();
         static immutable expected = [
             197, 57, 52, 3, 13, 194, 13,
             36, 117, 228, 8, 11, 111, 51,
             165, 3, 123, 31, 251, 113];
-        assert(digest == expected);
+        assert(testDigest == expected);
     }
 }
 
diff --git a/libphobos/src/std/exception.d b/libphobos/src/std/exception.d
index 129c05d4dcb..b699a8edea3 100644
--- a/libphobos/src/std/exception.d
+++ b/libphobos/src/std/exception.d
@@ -1069,9 +1069,9 @@ as the language is free to assume objects don't have internal pointers
 */
 bool doesPointTo(S, T, Tdummy=void)(auto ref const S source, ref const T target) @nogc @trusted pure nothrow
 if (__traits(isRef, source) || isDynamicArray!S ||
-    isPointer!S || is(S == class))
+    is(S : U*, U) || is(S == class))
 {
-    static if (isPointer!S || is(S == class) || is(S == interface))
+    static if (is(S : U*, U) || is(S == class) || is(S == interface))
     {
         const m = *cast(void**) &source;
         const b = cast(void*) &target;
@@ -1115,9 +1115,9 @@ bool doesPointTo(S, T)(auto ref const shared S source, ref const shared T target
 /// ditto
 bool mayPointTo(S, T, Tdummy=void)(auto ref const S source, ref const T target) @trusted pure nothrow
 if (__traits(isRef, source) || isDynamicArray!S ||
-    isPointer!S || is(S == class))
+    is(S : U*, U) || is(S == class))
 {
-    static if (isPointer!S || is(S == class) || is(S == interface))
+    static if (is(S : U*, U) || is(S == class) || is(S == interface))
     {
         const m = *cast(void**) &source;
         const b = cast(void*) &target;
diff --git a/libphobos/src/std/experimental/allocator/building_blocks/package.d b/libphobos/src/std/experimental/allocator/building_blocks/package.d
index 962ed91b882..6bc527d2374 100644
--- a/libphobos/src/std/experimental/allocator/building_blocks/package.d
+++ b/libphobos/src/std/experimental/allocator/building_blocks/package.d
@@ -147,7 +147,11 @@ Sizes through 3584 bytes are handled via freelists of staggered sizes. Sizes
 from 3585 bytes through 4072 KB are handled by a `BitmappedBlock` with a
 block size of 4 KB. Sizes above that are passed direct to the `GCAllocator`.
 
-----
+$(RUNNABLE_EXAMPLE
+    ----
+    import std.experimental.allocator;
+    import std.algorithm.comparison : max;
+
     alias FList = FreeList!(GCAllocator, 0, unbounded);
     alias A = Segregator!(
         8, FreeList!(GCAllocator, 0, 8),
@@ -157,8 +161,7 @@ block size of 4 KB. Sizes above that are passed direct to the `GCAllocator`.
         1024, Bucketizer!(FList, 513, 1024, 128),
         2048, Bucketizer!(FList, 1025, 2048, 256),
         3584, Bucketizer!(FList, 2049, 3584, 512),
-        4072 * 1024, AllocatorList!(
-            () => BitmappedBlock!(GCAllocator, 4096)(4072 * 1024)),
+        4072 * 1024, AllocatorList!(n => Region!GCAllocator(max(n, 1024 * 4096))),
         GCAllocator
     );
     A tuMalloc;
@@ -169,7 +172,8 @@ block size of 4 KB. Sizes above that are passed direct to the `GCAllocator`.
     assert(tuMalloc.expand(c, 14));
     tuMalloc.deallocate(b);
     tuMalloc.deallocate(c);
-----
+    ----
+)
 
 $(H2 Allocating memory for sharing across threads)
 
diff --git a/libphobos/src/std/experimental/allocator/package.d b/libphobos/src/std/experimental/allocator/package.d
index 217792676b5..7dbc47a6f02 100644
--- a/libphobos/src/std/experimental/allocator/package.d
+++ b/libphobos/src/std/experimental/allocator/package.d
@@ -27,13 +27,22 @@ $(TR $(TD Global) $(TD
     $(LREF theAllocator)
 ))
 $(TR $(TD Class interface) $(TD
-    $(LREF allocatorObject)
     $(LREF CAllocatorImpl)
+    $(LREF CSharedAllocatorImpl)
     $(LREF IAllocator)
+    $(LREF ISharedAllocator)
+))
+$(TR $(TD Structs) $(TD
+    $(LREF allocatorObject)
+    $(LREF RCIAllocator)
+    $(LREF RCISharedAllocator)
+    $(LREF sharedAllocatorObject)
+    $(LREF ThreadLocal)
 ))
 )
 
 Synopsis:
+$(RUNNABLE_EXAMPLE
 ---
 // Allocate an int, initialize it with 42
 int* p = theAllocator.make!int(42);
@@ -46,7 +55,10 @@ p = processAllocator.make!int(100);
 assert(*p == 100);
 // Destroy and deallocate
 processAllocator.dispose(p);
-
+---
+)
+$(RUNNABLE_EXAMPLE
+---
 // Create an array of 50 doubles initialized to -1.0
 double[] arr = theAllocator.makeArray!double(50, -1.0);
 // Append two zeros to it
@@ -56,6 +68,7 @@ theAllocator.shrinkArray(arr, 2);
 // Destroy and deallocate
 theAllocator.dispose(arr);
 ---
+)
 
 $(H2 Layered Structure)
 
diff --git a/libphobos/src/std/file.d b/libphobos/src/std/file.d
index 8d1b431215c..d0310966786 100644
--- a/libphobos/src/std/file.d
+++ b/libphobos/src/std/file.d
@@ -4986,21 +4986,20 @@ auto dirEntries(bool useDIP1000 = dip1000Enabled)
 {
     string[] listdir(string pathname)
     {
-        import std.algorithm;
-        import std.array;
-        import std.file;
-        import std.path;
+        import std.algorithm.iteration : map, filter;
+        import std.array : array;
+        import std.path : baseName;
 
-        return std.file.dirEntries(pathname, SpanMode.shallow)
+        return dirEntries(pathname, SpanMode.shallow)
             .filter!(a => a.isFile)
-            .map!((return a) => std.path.baseName(a.name))
+            .map!((return a) => baseName(a.name))
             .array;
     }
 
     // Can be safe only with -preview=dip1000
     @safe void main(string[] args)
     {
-        import std.stdio;
+        import std.stdio : writefln;
 
         string[] files = listdir(args[1]);
         writefln("%s", files);
diff --git a/libphobos/src/std/format/internal/write.d b/libphobos/src/std/format/internal/write.d
index 8089cfae914..32c82995fee 100644
--- a/libphobos/src/std/format/internal/write.d
+++ b/libphobos/src/std/format/internal/write.d
@@ -3011,7 +3011,7 @@ void enforceValidFormatSpec(T, Char)(scope const ref FormatSpec!Char f)
 /*
     `enum`s are formatted like their base value
  */
-void formatValueImpl(Writer, T, Char)(auto ref Writer w, const(T) val, scope const ref FormatSpec!Char f)
+void formatValueImpl(Writer, T, Char)(auto ref Writer w, T val, scope const ref FormatSpec!Char f)
 if (is(T == enum))
 {
     import std.array : appender;
@@ -3020,21 +3020,15 @@ if (is(T == enum))
     if (f.spec != 's')
         return formatValueImpl(w, cast(OriginalType!T) val, f);
 
-    static foreach (e; EnumMembers!T)
-    {
-        if (val == e)
-        {
-            formatValueImpl(w, __traits(identifier, e), f);
-            return;
-        }
-    }
+    foreach (immutable member; __traits(allMembers, T))
+        if (val == __traits(getMember, T, member))
+            return formatValueImpl(w, member, f);
 
     auto w2 = appender!string();
 
     // val is not a member of T, output cast(T) rawValue instead.
-    put(w2, "cast(");
-    put(w2, T.stringof);
-    put(w2, ")");
+    enum prefix = "cast(" ~ T.stringof ~ ")";
+    put(w2, prefix);
     static assert(!is(OriginalType!T == T), "OriginalType!" ~ T.stringof ~
                   "must not be equal to " ~ T.stringof);
 
@@ -3154,7 +3148,7 @@ if (isPointer!T && !is(T == enum) && !hasToString!(T, Char))
 
     auto a = iota(0, 10);
     auto b = iota(0, 10);
-    auto p = () @trusted { auto p = &a; return p; }();
+    auto p = () @trusted { auto result = &a; return result; }();
 
     assert(format("%s",p) != format("%s",b));
 }
diff --git a/libphobos/src/std/format/package.d b/libphobos/src/std/format/package.d
index d83f0281e59..f1d47055836 100644
--- a/libphobos/src/std/format/package.d
+++ b/libphobos/src/std/format/package.d
@@ -212,17 +212,17 @@ There are several flags that affect the outcome of the formatting.
 $(BOOKTABLE ,
    $(TR $(TH Flag) $(TH Semantics))
    $(TR $(TD $(B '-'))
-        $(TD When the formatted result is shorter then the value
-             given by the width parameter, the output is right
-             justified. With the $(B '-') flag this is changed
-             to left justification.
+        $(TD When the formatted result is shorter than the value
+             given by the width parameter, the output is left
+             justified. Without the $(B '-') flag, the output remains
+             right justified.
 
              There are two exceptions where the $(B '-') flag has a
              different meaning: (1) with $(B 'r') it denotes to use little
              endian and (2) in case of a compound indicator it means that
              no special handling of the members is applied.))
    $(TR $(TD $(B '='))
-        $(TD When the formatted result is shorter then the value
+        $(TD When the formatted result is shorter than the value
              given by the width parameter, the output is centered.
              If the central position is not possible it is moved slightly
              to the right. In this case, if $(B '-') flag is present in
@@ -1563,6 +1563,14 @@ char[] sformat(Char, Args...)(return scope char[] buf, scope const(Char)[] fmt,
     {
         char[] buf;
         size_t i;
+        void put(char c)
+        {
+            if (buf.length <= i)
+                throw new RangeError(__FILE__, __LINE__);
+
+            buf[i] = c;
+            i += 1;
+        }
         void put(dchar c)
         {
             char[4] enc;
@@ -1687,6 +1695,19 @@ if (isSomeString!(typeof(fmt)))
     assert(u == v);
 }
 
+@safe unittest // https://issues.dlang.org/show_bug.cgi?id=23488
+{
+    static struct R
+    {
+        string s = "Ü";
+        bool empty() { return s.length == 0; }
+        char front() { return s[0]; }
+        void popFront() { s = s[1 .. $]; }
+    }
+    char[2] buf;
+    assert(sformat(buf, "%s", R()) == "Ü");
+}
+
 version (StdUnittest)
 private void formatReflectTest(T)(ref T val, string fmt, string formatted, string fn = __FILE__, size_t ln = __LINE__)
 {
diff --git a/libphobos/src/std/format/write.d b/libphobos/src/std/format/write.d
index cbab51217ac..2aa45d724b5 100644
--- a/libphobos/src/std/format/write.d
+++ b/libphobos/src/std/format/write.d
@@ -1310,3 +1310,23 @@ void formatValue(Writer, T, Char)(auto ref Writer w, auto ref T val, scope const
     writer.formatValue(a, spec);
     assert(writer.data == "0");
 }
+
+// https://issues.dlang.org/show_bug.cgi?id=23400
+@safe pure unittest
+{
+    import std.range : nullSink;
+    import std.format.spec : singleSpec;
+
+    static struct S
+    {
+        // non-const opEquals method
+        bool opEquals(S rhs) { return false; }
+    }
+
+    enum E { a = S() }
+
+    E e;
+    auto writer = nullSink;
+    const spec = singleSpec("%s");
+    writer.formatValue(e, spec);
+}
diff --git a/libphobos/src/std/getopt.d b/libphobos/src/std/getopt.d
index b2399013b45..c85247f924e 100644
--- a/libphobos/src/std/getopt.d
+++ b/libphobos/src/std/getopt.d
@@ -558,7 +558,7 @@ private template optionValidator(A...)
     import std.format : format;
 
     enum fmt = "getopt validator: %s (at position %d)";
-    enum isReceiver(T) = isPointer!T || (is(T == function)) || (is(T == delegate));
+    enum isReceiver(T) = is(T : U*, U) || (is(T == function)) || (is(T == delegate));
     enum isOptionStr(T) = isSomeString!T || isSomeChar!T;
 
     auto validator()
diff --git a/libphobos/src/std/math/hardware.d b/libphobos/src/std/math/hardware.d
index 40e42da74f9..81c7302b4c1 100644
--- a/libphobos/src/std/math/hardware.d
+++ b/libphobos/src/std/math/hardware.d
@@ -37,13 +37,6 @@ version (RISCV64)   version = RISCV_Any;
 version (D_InlineAsm_X86)    version = InlineAsm_X86_Any;
 version (D_InlineAsm_X86_64) version = InlineAsm_X86_Any;
 
-version (InlineAsm_X86_Any) version = InlineAsm_X87;
-version (InlineAsm_X87)
-{
-    static assert(real.mant_dig == 64);
-    version (CRuntime_Microsoft) version = InlineAsm_X87_MSVC;
-}
-
 version (X86_64) version = StaticallyHaveSSE;
 version (X86) version (OSX) version = StaticallyHaveSSE;
 
@@ -76,19 +69,6 @@ version (D_HardFloat)
     version (IeeeFlagsSupport) version = FloatingPointControlSupport;
 }
 
-version (GNU)
-{
-    // The compiler can unexpectedly rearrange floating point operations and
-    // access to the floating point status flags when optimizing. This means
-    // ieeeFlags tests cannot be reliably checked in optimized code.
-    // See https://github.com/ldc-developers/ldc/issues/888
-}
-else
-{
-    version = IeeeFlagsUnittest;
-    version = FloatingPointControlUnittest;
-}
-
 version (IeeeFlagsSupport)
 {
 
@@ -368,7 +348,7 @@ public:
 }
 
 ///
-version (IeeeFlagsUnittest)
+version (StdDdoc)
 @safe unittest
 {
     import std.math.traits : isNaN;
@@ -376,17 +356,14 @@ version (IeeeFlagsUnittest)
     static void func() {
         int a = 10 * 10;
     }
-    pragma(inline, false) static void blockopt(ref real x) {}
     real a = 3.5;
     // Set all the flags to zero
     resetIeeeFlags();
     assert(!ieeeFlags.divByZero);
-    blockopt(a); // avoid constant propagation by the optimizer
     // Perform a division by zero.
     a /= 0.0L;
     assert(a == real.infinity);
     assert(ieeeFlags.divByZero);
-    blockopt(a); // avoid constant propagation by the optimizer
     // Create a NaN
     a *= 0.0L;
     assert(ieeeFlags.invalid);
@@ -399,7 +376,33 @@ version (IeeeFlagsUnittest)
     assert(ieeeFlags == f);
 }
 
-version (IeeeFlagsUnittest)
+@safe unittest
+{
+    import std.math.traits : isNaN;
+
+    static void func() {
+        int a = 10 * 10;
+    }
+    real a = 3.5;
+    // Set all the flags to zero
+    resetIeeeFlags();
+    assert(!ieeeFlags.divByZero);
+    // Perform a division by zero.
+    a = forceDivOp(a, 0.0L);
+    assert(a == real.infinity);
+    assert(ieeeFlags.divByZero);
+    // Create a NaN
+    a = forceMulOp(a, 0.0L);
+    assert(ieeeFlags.invalid);
+    assert(isNaN(a));
+
+    // Check that calling func() has no effect on the
+    // status flags.
+    IeeeFlags f = ieeeFlags;
+    func();
+    assert(ieeeFlags == f);
+}
+
 @safe unittest
 {
     import std.meta : AliasSeq;
@@ -412,27 +415,26 @@ version (IeeeFlagsUnittest)
 
     static foreach (T; AliasSeq!(float, double, real))
     {{
-        T x; /* Needs to be here to trick -O. It would optimize away the
-            calculations if x were local to the function literals. */
+        T x; // Needs to be here to avoid `call without side effects` warning.
         auto tests = [
             Test(
-                () { x = 1; x += 0.1L; },
+                () { x = forceAddOp!T(1, 0.1L); },
                 () => ieeeFlags.inexact
             ),
             Test(
-                () { x = T.min_normal; x /= T.max; },
+                () { x = forceDivOp!T(T.min_normal, T.max); },
                 () => ieeeFlags.underflow
             ),
             Test(
-                () { x = T.max; x += T.max; },
+                () { x = forceAddOp!T(T.max, T.max); },
                 () => ieeeFlags.overflow
             ),
             Test(
-                () { x = 1; x /= 0; },
+                () { x = forceDivOp!T(1, 0); },
                 () => ieeeFlags.divByZero
             ),
             Test(
-                () { x = 0; x /= 0; },
+                () { x = forceDivOp!T(0, 0); },
                 () => ieeeFlags.invalid
             )
         ];
@@ -453,14 +455,24 @@ void resetIeeeFlags() @trusted nothrow @nogc
 }
 
 ///
+version (StdDdoc)
 @safe unittest
 {
-    pragma(inline, false) static void blockopt(ref real x) {}
     resetIeeeFlags();
     real a = 3.5;
-    blockopt(a); // avoid constant propagation by the optimizer
     a /= 0.0L;
-    blockopt(a); // avoid constant propagation by the optimizer
+    assert(a == real.infinity);
+    assert(ieeeFlags.divByZero);
+
+    resetIeeeFlags();
+    assert(!ieeeFlags.divByZero);
+}
+
+@safe unittest
+{
+    resetIeeeFlags();
+    real a = 3.5;
+    a = forceDivOp(a, 0.0L);
     assert(a == real.infinity);
     assert(ieeeFlags.divByZero);
 
@@ -475,25 +487,39 @@ void resetIeeeFlags() @trusted nothrow @nogc
 }
 
 ///
+version (StdDdoc)
 @safe nothrow unittest
 {
     import std.math.traits : isNaN;
 
-    pragma(inline, false) static void blockopt(ref real x) {}
     resetIeeeFlags();
     real a = 3.5;
-    blockopt(a); // avoid constant propagation by the optimizer
 
     a /= 0.0L;
     assert(a == real.infinity);
     assert(ieeeFlags.divByZero);
-    blockopt(a); // avoid constant propagation by the optimizer
 
     a *= 0.0L;
     assert(isNaN(a));
     assert(ieeeFlags.invalid);
 }
 
+@safe nothrow unittest
+{
+    import std.math.traits : isNaN;
+
+    resetIeeeFlags();
+    real a = 3.5;
+
+    a = forceDivOp(a, 0.0L);
+    assert(a == real.infinity);
+    assert(ieeeFlags.divByZero);
+
+    a = forceMulOp(a, 0.0L);
+    assert(isNaN(a));
+    assert(ieeeFlags.invalid);
+}
+
 } // IeeeFlagsSupport
 
 
@@ -1100,7 +1126,6 @@ private:
 }
 
 ///
-version (FloatingPointControlUnittest)
 @safe unittest
 {
     import std.math.rounding : lrint;
@@ -1154,32 +1179,27 @@ version (FloatingPointControlUnittest)
     ensureDefaults();
 }
 
-version (FloatingPointControlUnittest)
 @safe unittest // rounding
 {
     import std.meta : AliasSeq;
 
     static T addRound(T)(uint rm)
     {
-        pragma(inline, false) static void blockopt(ref T x) {}
         pragma(inline, false);
         FloatingPointControl fpctrl;
         fpctrl.rounding = rm;
         T x = 1;
-        blockopt(x); // avoid constant propagation by the optimizer
-        x += 0.1L;
+        x = forceAddOp(x, 0.1L);
         return x;
     }
 
     static T subRound(T)(uint rm)
     {
-        pragma(inline, false) static void blockopt(ref T x) {}
         pragma(inline, false);
         FloatingPointControl fpctrl;
         fpctrl.rounding = rm;
         T x = -1;
-        blockopt(x); // avoid constant propagation by the optimizer
-        x -= 0.1L;
+        x = forceSubOp(x, 0.1L);
         return x;
     }
 
@@ -1210,4 +1230,16 @@ version (FloatingPointControlUnittest)
     }}
 }
 
+} // FloatingPointControlSupport
+
+version (StdUnittest)
+{
+    // These helpers are intended to avoid constant propagation by the optimizer.
+    pragma(inline, false) private @safe
+    {
+        T forceAddOp(T)(T x, T y) { return x + y; }
+        T forceSubOp(T)(T x, T y) { return x - y; }
+        T forceMulOp(T)(T x, T y) { return x * y; }
+        T forceDivOp(T)(T x, T y) { return x / y; }
+    }
 }
diff --git a/libphobos/src/std/process.d b/libphobos/src/std/process.d
index d4fe8a1c7e8..3eaa2835249 100644
--- a/libphobos/src/std/process.d
+++ b/libphobos/src/std/process.d
@@ -1428,7 +1428,7 @@ version (Posix) @system unittest
     for (; environ[i] != null; ++i)
     {
         assert(e2[i] != null);
-        import core.stdc.string;
+        import core.stdc.string : strcmp;
         assert(strcmp(e2[i], environ[i]) == 0);
     }
     assert(e2[i] == null);
@@ -1732,7 +1732,9 @@ version (Posix) @system unittest
     // Pipes
     void testPipes(Config config)
     {
-        import std.file, std.uuid, core.thread, std.exception;
+        import std.file : tempDir, exists, remove;
+        import std.uuid : randomUUID;
+        import std.exception : collectException;
         auto pipei = pipe();
         auto pipeo = pipe();
         auto pipee = pipe();
@@ -1753,11 +1755,14 @@ version (Posix) @system unittest
     // Files
     void testFiles(Config config)
     {
-        import std.ascii, std.file, std.uuid, core.thread, std.exception;
+        import std.ascii : newline;
+        import std.file : tempDir, exists, remove, readText, write;
+        import std.uuid : randomUUID;
+        import std.exception : collectException;
         auto pathi = buildPath(tempDir(), randomUUID().toString());
         auto patho = buildPath(tempDir(), randomUUID().toString());
         auto pathe = buildPath(tempDir(), randomUUID().toString());
-        std.file.write(pathi, "INPUT"~std.ascii.newline);
+        write(pathi, "INPUT" ~ newline);
         auto filei = File(pathi, "r");
         auto fileo = File(patho, "w");
         auto filee = File(pathe, "w");
diff --git a/libphobos/src/std/range/package.d b/libphobos/src/std/range/package.d
index 91971342d9a..888ac1a5d86 100644
--- a/libphobos/src/std/range/package.d
+++ b/libphobos/src/std/range/package.d
@@ -3774,10 +3774,17 @@ private:
         alias fun = Fun[0];
 
     enum returnByRef_ = (functionAttributes!fun & FunctionAttribute.ref_) ? true : false;
+
+    import std.traits : hasIndirections;
+    static if (!hasIndirections!(ReturnType!fun))
+        alias RetType = Unqual!(ReturnType!fun);
+    else
+        alias RetType = ReturnType!fun;
+
     static if (returnByRef_)
-        ReturnType!fun *elem_;
+        RetType *elem_;
     else
-        ReturnType!fun elem_;
+        RetType elem_;
 public:
     /// Range primitives
     enum empty = false;
@@ -3866,6 +3873,13 @@ public:
     assert(g.front == f + 5);
 }
 
+// https://issues.dlang.org/show_bug.cgi?id=23319
+@safe pure nothrow unittest
+{
+    auto b = generate!(() => const(int)(42));
+    assert(b.front == 42);
+}
+
 /**
 Repeats the given forward range ad infinitum. If the original range is
 infinite (fact that would make `Cycle` the identity application),
@@ -6856,6 +6870,7 @@ if (!isIntegral!(CommonType!(B, E)) &&
             assert(!empty);
             ++current;
         }
+        @property auto save() { return this; }
     }
     return Result(begin, end);
 }
@@ -6890,6 +6905,13 @@ if (!isIntegral!(CommonType!(B, E)) &&
     assert(i2.equal([3, 4, 0, 1 ]));
 }
 
+// https://issues.dlang.org/show_bug.cgi?id=23453
+@safe unittest
+{
+    auto r = iota('a', 'z');
+    static assert(isForwardRange!(typeof(r)));
+}
+
 /**
    Options for the $(LREF FrontTransversal) and $(LREF Transversal) ranges
    (below).
diff --git a/libphobos/src/std/socket.d b/libphobos/src/std/socket.d
index fb2c2d42253..593052e5a82 100644
--- a/libphobos/src/std/socket.d
+++ b/libphobos/src/std/socket.d
@@ -2628,7 +2628,7 @@ private:
     AddressFamily _family;
 
     version (Windows)
-        bool _blocking = false;         /// Property to get or set whether the socket is blocking or nonblocking.
+        bool _blocking = true;         /// Property to get or set whether the socket is blocking or nonblocking.
 
     // The WinSock timeouts seem to be effectively skewed by a constant
     // offset of about half a second (value in milliseconds). This has
@@ -2641,22 +2641,22 @@ private:
     {
         if (runSlowTests)
         softUnittest({
-            import std.datetime.stopwatch;
-            import std.typecons;
+            import std.datetime.stopwatch : StopWatch;
+            import std.typecons : Yes;
 
             enum msecs = 1000;
             auto pair = socketPair();
-            auto sock = pair[0];
-            sock.setOption(SocketOptionLevel.SOCKET,
+            auto testSock = pair[0];
+            testSock.setOption(SocketOptionLevel.SOCKET,
                 SocketOption.RCVTIMEO, dur!"msecs"(msecs));
 
             auto sw = StopWatch(Yes.autoStart);
             ubyte[1] buf;
-            sock.receive(buf);
+            testSock.receive(buf);
             sw.stop();
 
             Duration readBack = void;
-            sock.getOption(SocketOptionLevel.SOCKET, SocketOption.RCVTIMEO, readBack);
+            testSock.getOption(SocketOptionLevel.SOCKET, SocketOption.RCVTIMEO, readBack);
 
             assert(readBack.total!"msecs" == msecs);
             assert(sw.peek().total!"msecs" > msecs - 100 && sw.peek().total!"msecs" < msecs + 100);
@@ -2750,6 +2750,21 @@ public:
         return sock;
     }
 
+    /**
+     * Releases the underlying socket handle from the Socket object. Once it
+     * is released, you cannot use the Socket object's methods anymore. This
+     * also means the Socket destructor will no longer close the socket - it
+     * becomes your responsibility.
+     *
+     * To get the handle without releasing it, use the `handle` property.
+     */
+    @property socket_t release() pure nothrow @nogc
+    {
+        auto h = sock;
+        this.sock = socket_t.init;
+        return h;
+    }
+
     /**
      * Get/set socket's blocking flag.
      *
diff --git a/libphobos/src/std/stdio.d b/libphobos/src/std/stdio.d
index ffd6da8c4db..802aa128c6e 100644
--- a/libphobos/src/std/stdio.d
+++ b/libphobos/src/std/stdio.d
@@ -52,7 +52,7 @@ import std.algorithm.mutation : copy;
 import std.meta : allSatisfy;
 import std.range : ElementEncodingType, empty, front, isBidirectionalRange,
     isInputRange, isSomeFiniteCharInputRange, put;
-import std.traits : isSomeChar, isSomeString, Unqual, isPointer;
+import std.traits : isSomeChar, isSomeString, Unqual;
 import std.typecons : Flag, No, Yes;
 
 /++
@@ -768,7 +768,7 @@ Throws: `ErrnoException` in case of error.
             _name = name;
     }
 
-    @system unittest // Test changing filename
+    @safe unittest // Test changing filename
     {
         import std.exception : assertThrown, assertNotThrown;
         static import std.file;
@@ -790,7 +790,7 @@ Throws: `ErrnoException` in case of error.
 
     version (CRuntime_DigitalMars) {} else // Not implemented
     version (CRuntime_Microsoft) {} else // Not implemented
-    @system unittest // Test changing mode
+    @safe unittest // Test changing mode
     {
         import std.exception : assertThrown, assertNotThrown;
         static import std.file;
@@ -1853,15 +1853,15 @@ void main()
 }
 ---
 */
-    S readln(S = string)(dchar terminator = '\n')
+    S readln(S = string)(dchar terminator = '\n') @safe
     if (isSomeString!S)
     {
         Unqual!(ElementEncodingType!S)[] buf;
         readln(buf, terminator);
-        return cast(S) buf;
+        return (() @trusted => cast(S) buf)();
     }
 
-    @system unittest
+    @safe unittest
     {
         import std.algorithm.comparison : equal;
         static import std.file;
@@ -1885,7 +1885,7 @@ void main()
         }}
     }
 
-    @system unittest
+    @safe unittest
     {
         static import std.file;
         import std.typecons : Tuple;
@@ -1984,7 +1984,7 @@ void main()
 This is actually what $(LREF byLine) does internally, so its usage
 is recommended if you want to process a complete file.
 */
-    size_t readln(C)(ref C[] buf, dchar terminator = '\n')
+    size_t readln(C)(ref C[] buf, dchar terminator = '\n') @safe
     if (isSomeChar!C && is(Unqual!C == C) && !is(C == enum))
     {
         import std.exception : enforce;
@@ -2020,9 +2020,8 @@ is recommended if you want to process a complete file.
         }
     }
 
-    @system unittest
+    @safe unittest
     {
-        // @system due to readln
         static import std.file;
         auto deleteme = testFilename();
         std.file.write(deleteme, "123\n456789");
@@ -2039,7 +2038,7 @@ is recommended if you want to process a complete file.
     }
 
     // https://issues.dlang.org/show_bug.cgi?id=15293
-    @system unittest
+    @safe unittest
     {
         // @system due to readln
         static import std.file;
@@ -2063,7 +2062,7 @@ is recommended if you want to process a complete file.
     }
 
 /** ditto */
-    size_t readln(C, R)(ref C[] buf, R terminator)
+    size_t readln(C, R)(ref C[] buf, R terminator) @safe
     if (isSomeChar!C && is(Unqual!C == C) && !is(C == enum) &&
         isBidirectionalRange!R && is(typeof(terminator.front == dchar.init)))
     {
@@ -2093,7 +2092,7 @@ is recommended if you want to process a complete file.
         return buf.length;
     }
 
-    @system unittest
+    @safe unittest
     {
         static import std.file;
         import std.typecons : Tuple;
@@ -3735,9 +3734,8 @@ void main()
     assert(f.tell == 0);
 }
 
-@system unittest
+@safe unittest
 {
-    // @system due to readln
     static import std.file;
     import std.range : chain, only, repeat;
     import std.range.primitives : isOutputRange;
@@ -5169,13 +5167,13 @@ Initialize with a message and an error code.
     }
 
 /** Convenience functions that throw an `StdioException`. */
-    static void opCall(string msg)
+    static void opCall(string msg) @safe
     {
         throw new StdioException(msg);
     }
 
 /// ditto
-    static void opCall()
+    static void opCall() @safe
     {
         throw new StdioException(null, core.stdc.errno.errno);
     }
@@ -5388,7 +5386,7 @@ private struct ReadlnAppender
     size_t pos;
     bool safeAppend = false;
 
-    void initialize(char[] b)
+    void initialize(char[] b) @safe
     {
         buf = b;
         pos = 0;
@@ -5445,7 +5443,7 @@ private struct ReadlnAppender
         foreach (c; ubuf)
             buf.ptr[pos++] = c;
     }
-    void putonly(char[] b) @trusted
+    void putonly(const char[] b) @trusted
     {
         import core.stdc.string : memcpy;
         assert(pos == 0);   // assume this is the only put call
@@ -5457,28 +5455,60 @@ private struct ReadlnAppender
     }
 }
 
-// Private implementation of readln
-private size_t readlnImpl(FILE* fps, ref char[] buf, dchar terminator, File.Orientation orientation)
+private struct LockedFile
 {
-    version (DIGITAL_MARS_STDIO)
+    private @system _iobuf* fp;
+
+    this(FILE* fps) @trusted
     {
         _FLOCK(fps);
-        scope(exit) _FUNLOCK(fps);
+        // Since fps is now locked, we can cast away shared
+        fp = cast(_iobuf*) fps;
+    }
+
+    @disable this();
+    @disable this(this);
+    @disable void opAssign(LockedFile);
 
-        /* Since fps is now locked, we can create an "unshared" version
-         * of fp.
-         */
-        auto fp = cast(_iobuf*) fps;
+    // these use unlocked fgetc calls
+    @trusted fgetc() { return _FGETC(fp); }
+    @trusted fgetwc() { return _FGETWC(fp); }
 
+    ~this() @trusted
+    {
+        _FUNLOCK(cast(FILE*) fp);
+    }
+}
+
+@safe unittest
+{
+    void f() @safe
+    {
+        FILE* fps;
+        auto lf = LockedFile(fps);
+        static assert(!__traits(compiles, lf = LockedFile(fps)));
+        version (ShouldFail)
+        {
+            lf.fps = null; // error with -preview=systemVariables
+        }
+    }
+}
+
+// Private implementation of readln
+private size_t readlnImpl(FILE* fps, ref char[] buf, dchar terminator, File.Orientation orientation) @safe
+{
+    version (DIGITAL_MARS_STDIO)
+    return () @trusted {
+        auto lf = LockedFile(fps);
         ReadlnAppender app;
         app.initialize(buf);
 
-        if (__fhnd_info[fp._file] & FHND_WCHAR)
+        if (__fhnd_info[lf.fp._file] & FHND_WCHAR)
         {   /* Stream is in wide characters.
              * Read them and convert to chars.
              */
             static assert(wchar_t.sizeof == 2);
-            for (int c = void; (c = _FGETWC(fp)) != -1; )
+            for (int c = void; (c = lf.fgetwc()) != -1; )
             {
                 if ((c & ~0x7F) == 0)
                 {
@@ -5491,7 +5521,7 @@ private size_t readlnImpl(FILE* fps, ref char[] buf, dchar terminator, File.Orie
                     if (c >= 0xD800 && c <= 0xDBFF)
                     {
                         int c2 = void;
-                        if ((c2 = _FGETWC(fp)) != -1 ||
+                        if ((c2 = lf.fgetwc()) != -1 ||
                                 c2 < 0xDC00 && c2 > 0xDFFF)
                         {
                             StdioException("unpaired UTF-16 surrogate");
@@ -5504,8 +5534,7 @@ private size_t readlnImpl(FILE* fps, ref char[] buf, dchar terminator, File.Orie
             if (ferror(fps))
                 StdioException();
         }
-
-        else if (fp._flag & _IONBF)
+        else if (lf.fp._flag & _IONBF)
         {
             /* Use this for unbuffered I/O, when running
              * across buffer boundaries, or for any but the common
@@ -5513,7 +5542,7 @@ private size_t readlnImpl(FILE* fps, ref char[] buf, dchar terminator, File.Orie
              */
         L1:
             int c;
-            while ((c = _FGETC(fp)) != -1)
+            while ((c = lf.fgetc()) != -1)
             {
                 app.putchar(cast(char) c);
                 if (c == terminator)
@@ -5529,10 +5558,10 @@ private size_t readlnImpl(FILE* fps, ref char[] buf, dchar terminator, File.Orie
         }
         else
         {
-            int u = fp._cnt;
-            char* p = fp._ptr;
+            int u = lf.fp._cnt;
+            char* p = lf.fp._ptr;
             int i;
-            if (fp._flag & _IOTRAN)
+            if (lf.fp._flag & _IOTRAN)
             {   /* Translated mode ignores \r and treats ^Z as end-of-file
                  */
                 char c;
@@ -5574,28 +5603,22 @@ private size_t readlnImpl(FILE* fps, ref char[] buf, dchar terminator, File.Orie
                 }
                 app.putonly(p[0 .. i]);
             }
-            fp._cnt -= i;
-            fp._ptr += i;
+            lf.fp._cnt -= i;
+            lf.fp._ptr += i;
         }
 
         buf = app.data;
         return buf.length;
-    }
+    }();
     else version (MICROSOFT_STDIO)
     {
-        _FLOCK(fps);
-        scope(exit) _FUNLOCK(fps);
-
-        /* Since fps is now locked, we can create an "unshared" version
-         * of fp.
-         */
-        auto fp = cast(_iobuf*) fps;
+        auto lf = LockedFile(fps);
 
         ReadlnAppender app;
         app.initialize(buf);
 
         int c;
-        while ((c = _FGETC(fp)) != -1)
+        while ((c = lf.fgetc()) != -1)
         {
             app.putchar(cast(char) c);
             if (c == terminator)
@@ -5613,21 +5636,18 @@ private size_t readlnImpl(FILE* fps, ref char[] buf, dchar terminator, File.Orie
     }
     else static if (__traits(compiles, core.sys.posix.stdio.getdelim))
     {
-        import core.stdc.stdlib : free;
-        import core.stdc.wchar_ : fwide;
-
         if (orientation == File.Orientation.wide)
         {
+            import core.stdc.wchar_ : fwide;
+
+            auto lf = LockedFile(fps);
             /* Stream is in wide characters.
              * Read them and convert to chars.
              */
-            _FLOCK(fps);
-            scope(exit) _FUNLOCK(fps);
-            auto fp = cast(_iobuf*) fps;
             version (Windows)
             {
                 buf.length = 0;
-                for (int c = void; (c = _FGETWC(fp)) != -1; )
+                for (int c = void; (c = lf.fgetwc()) != -1; )
                 {
                     if ((c & ~0x7F) == 0)
                     {   buf ~= c;
@@ -5639,7 +5659,7 @@ private size_t readlnImpl(FILE* fps, ref char[] buf, dchar terminator, File.Orie
                         if (c >= 0xD800 && c <= 0xDBFF)
                         {
                             int c2 = void;
-                            if ((c2 = _FGETWC(fp)) != -1 ||
+                            if ((c2 = lf.fgetwc()) != -1 ||
                                     c2 < 0xDC00 && c2 > 0xDFFF)
                             {
                                 StdioException("unpaired UTF-16 surrogate");
@@ -5650,14 +5670,14 @@ private size_t readlnImpl(FILE* fps, ref char[] buf, dchar terminator, File.Orie
                         encode(buf, c);
                     }
                 }
-                if (ferror(fp))
+                if (ferror(fps))
                     StdioException();
                 return buf.length;
             }
             else version (Posix)
             {
                 buf.length = 0;
-                for (int c; (c = _FGETWC(fp)) != -1; )
+                for (int c; (c = lf.fgetwc()) != -1; )
                 {
                     import std.utf : encode;
 
@@ -5677,47 +5697,49 @@ private size_t readlnImpl(FILE* fps, ref char[] buf, dchar terminator, File.Orie
                 static assert(0);
             }
         }
+        return () @trusted {
+            import core.stdc.stdlib : free;
 
-        static char *lineptr = null;
-        static size_t n = 0;
-        scope(exit)
-        {
-            if (n > 128 * 1024)
+            static char *lineptr = null;
+            static size_t n = 0;
+            scope(exit)
             {
-                // Bound memory used by readln
-                free(lineptr);
-                lineptr = null;
-                n = 0;
+                if (n > 128 * 1024)
+                {
+                    // Bound memory used by readln
+                    free(lineptr);
+                    lineptr = null;
+                    n = 0;
+                }
             }
-        }
 
-        auto s = core.sys.posix.stdio.getdelim(&lineptr, &n, terminator, fps);
-        if (s < 0)
-        {
-            if (ferror(fps))
-                StdioException();
-            buf.length = 0;                // end of file
-            return 0;
-        }
+            const s = core.sys.posix.stdio.getdelim(&lineptr, &n, terminator, fps);
+            if (s < 0)
+            {
+                if (ferror(fps))
+                    StdioException();
+                buf.length = 0;                // end of file
+                return 0;
+            }
 
-        if (s <= buf.length)
-        {
-            buf = buf[0 .. s];
-            buf[] = lineptr[0 .. s];
-        }
-        else
-        {
-            buf = lineptr[0 .. s].dup;
-        }
-        return s;
+            const line = lineptr[0 .. s];
+            if (s <= buf.length)
+            {
+                buf = buf[0 .. s];
+                buf[] = line;
+            }
+            else
+            {
+                buf = line.dup;
+            }
+            return s;
+        }();
     }
     else // version (NO_GETDELIM)
     {
         import core.stdc.wchar_ : fwide;
 
-        _FLOCK(fps);
-        scope(exit) _FUNLOCK(fps);
-        auto fp = cast(_iobuf*) fps;
+        auto lf = LockedFile(fps);
         if (orientation == File.Orientation.wide)
         {
             /* Stream is in wide characters.
@@ -5726,7 +5748,7 @@ private size_t readlnImpl(FILE* fps, ref char[] buf, dchar terminator, File.Orie
             version (Windows)
             {
                 buf.length = 0;
-                for (int c; (c = _FGETWC(fp)) != -1; )
+                for (int c; (c = lf.fgetwc()) != -1; )
                 {
                     if ((c & ~0x7F) == 0)
                     {   buf ~= c;
@@ -5738,7 +5760,7 @@ private size_t readlnImpl(FILE* fps, ref char[] buf, dchar terminator, File.Orie
                         if (c >= 0xD800 && c <= 0xDBFF)
                         {
                             int c2 = void;
-                            if ((c2 = _FGETWC(fp)) != -1 ||
+                            if ((c2 = lf.fgetwc()) != -1 ||
                                     c2 < 0xDC00 && c2 > 0xDFFF)
                             {
                                 StdioException("unpaired UTF-16 surrogate");
@@ -5749,7 +5771,7 @@ private size_t readlnImpl(FILE* fps, ref char[] buf, dchar terminator, File.Orie
                         encode(buf, c);
                     }
                 }
-                if (ferror(fp))
+                if (ferror(fps))
                     StdioException();
                 return buf.length;
             }
@@ -5757,7 +5779,7 @@ private size_t readlnImpl(FILE* fps, ref char[] buf, dchar terminator, File.Orie
             {
                 import std.utf : encode;
                 buf.length = 0;
-                for (int c; (c = _FGETWC(fp)) != -1; )
+                for (int c; (c = lf.fgetwc()) != -1; )
                 {
                     if ((c & ~0x7F) == 0)
                         buf ~= cast(char) c;
@@ -5780,7 +5802,7 @@ private size_t readlnImpl(FILE* fps, ref char[] buf, dchar terminator, File.Orie
         // First, fill the existing buffer
         for (size_t bufPos = 0; bufPos < buf.length; )
         {
-            immutable c = _FGETC(fp);
+            immutable c = lf.fgetc();
             if (c == -1)
             {
                 buf.length = bufPos;
@@ -5795,7 +5817,7 @@ private size_t readlnImpl(FILE* fps, ref char[] buf, dchar terminator, File.Orie
             }
         }
         // Then, append to it
-        for (int c; (c = _FGETC(fp)) != -1; )
+        for (int c; (c = lf.fgetc()) != -1; )
         {
             buf ~= cast(char) c;
             if (c == terminator)
diff --git a/libphobos/src/std/sumtype.d b/libphobos/src/std/sumtype.d
index ee2d73a1233..4e76156b1cb 100644
--- a/libphobos/src/std/sumtype.d
+++ b/libphobos/src/std/sumtype.d
@@ -1952,10 +1952,10 @@ private template matchImpl(Flag!"exhaustive" exhaustive, handlers...)
         // An array that maps caseIds to handler indices ("hids").
         enum matches = ()
         {
-            size_t[numCases] matches;
+            size_t[numCases] result;
 
             // Workaround for https://issues.dlang.org/show_bug.cgi?id=19561
-            foreach (ref match; matches)
+            foreach (ref match; result)
             {
                 match = noMatch;
             }
@@ -1966,15 +1966,15 @@ private template matchImpl(Flag!"exhaustive" exhaustive, handlers...)
                 {
                     static if (canMatch!(handler, valueTypes!caseId))
                     {
-                        if (matches[caseId] == noMatch)
+                        if (result[caseId] == noMatch)
                         {
-                            matches[caseId] = hid;
+                            result[caseId] = hid;
                         }
                     }
                 }
             }
 
-            return matches;
+            return result;
         }();
 
         import std.algorithm.searching : canFind;
diff --git a/libphobos/src/std/traits.d b/libphobos/src/std/traits.d
index 1cbff8414e3..e5f305bf83c 100644
--- a/libphobos/src/std/traits.d
+++ b/libphobos/src/std/traits.d
@@ -889,10 +889,10 @@ private template fqnType(T,
             );
         }
     }
-    else static if (isPointer!T)
+    else static if (is(T : U*, U))
     {
         enum fqnType = chain!(
-            fqnType!(PointerTarget!T, qualifiers) ~ "*"
+            fqnType!(U, qualifiers) ~ "*"
         );
     }
     else static if (is(T : __vector(V[N]), V, size_t N))
@@ -3925,8 +3925,8 @@ template hasStaticMember(T, string member)
 {
     static if (__traits(hasMember, T, member))
     {
-        static if (isPointer!T)
-            alias U = PointerTarget!T;
+        static if (is(T : V*, V))
+            alias U = V;
         else
             alias U = T;
 
@@ -5446,8 +5446,8 @@ private template isStorageClassImplicitlyConvertible(From, To)
 {
     alias Pointify(T) = void*;
 
-    enum isStorageClassImplicitlyConvertible = isImplicitlyConvertible!(
-            ModifyTypePreservingTQ!(Pointify, From),
+    enum isStorageClassImplicitlyConvertible = is(
+            ModifyTypePreservingTQ!(Pointify, From) :
             ModifyTypePreservingTQ!(Pointify,   To) );
 }
 
@@ -7138,7 +7138,7 @@ enum bool isSIMDVector(T) = is(T : __vector(V[N]), V, size_t N);
 /**
  * Detect whether type `T` is a pointer.
  */
-enum bool isPointer(T) = is(T == U*, U) && __traits(isScalar, T);
+enum bool isPointer(T) = is(T == U*, U);
 
 ///
 @safe unittest
@@ -8847,6 +8847,14 @@ version (StdUnittest)
     static assert(__traits(compiles, getSymbolsByUDA!(mixin(__MODULE__), "Issue20054")));
 }
 
+private template isAliasSeq(Args...)
+{
+    static if (Args.length != 1)
+        enum isAliasSeq = true;
+    else
+        enum isAliasSeq = false;
+}
+
 private template getSymbolsByUDAImpl(alias symbol, alias attribute, names...)
 {
     import std.meta : Alias, AliasSeq, Filter;
@@ -8868,12 +8876,12 @@ 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 (!__traits(compiles, hasUDA!(member, attribute)))
+            static if (isAliasSeq!member || isType!member)
             {
                 alias getSymbolsByUDAImpl = tail;
             }
-            // Get overloads for functions, in case different overloads have different sets of UDAs.
-            else static if (isFunction!member)
+            // If a symbol is overloaded, get UDAs for each overload (including templated overlaods).
+            else static if (__traits(getOverloads, symbol, names[0], true).length > 0)
             {
                 enum hasSpecificUDA(alias member) = hasUDA!(member, attribute);
                 alias overloadsWithUDA = Filter!(hasSpecificUDA, __traits(getOverloads, symbol, names[0]));
diff --git a/libphobos/src/std/typecons.d b/libphobos/src/std/typecons.d
index 231ac9302a3..e83b6171334 100644
--- a/libphobos/src/std/typecons.d
+++ b/libphobos/src/std/typecons.d
@@ -5536,7 +5536,7 @@ private static:
     }
 
     // handle each overload set
-    private string generateCodeForOverloadSet(alias oset)() @property
+    string generateCodeForOverloadSet(alias oset)() @property
     {
         string code = "";
 
@@ -5666,7 +5666,7 @@ private static:
      * "ref int a0, real a1, ..."
      */
     static struct GenParams { string imports, params; }
-    private GenParams generateParameters(string myFuncInfo, func...)()
+    GenParams generateParameters(string myFuncInfo, func...)()
     {
         alias STC = ParameterStorageClass;
         alias stcs = ParameterStorageClassTuple!(func);
@@ -5716,7 +5716,7 @@ private static:
 
     // Returns D code which enumerates n parameter variables using comma as the
     // separator.  "a0, a1, a2, a3"
-    private string enumerateParameters(size_t n)() @property
+    string enumerateParameters(size_t n)() @property
     {
         string params = "";
 
@@ -8782,7 +8782,7 @@ if (alignment > 0 && !((alignment - 1) & alignment))
     {
         void test(size_t size)
         {
-            import core.stdc.stdlib;
+            import core.stdc.stdlib : alloca;
             cast(void) alloca(size);
             alignmentTest();
         }
@@ -9253,7 +9253,7 @@ public:
     }
 
     Base opCast(B)() const
-        if (isImplicitlyConvertible!(Base, B))
+        if (is(Base : B))
     {
         return mValue;
     }
diff --git a/libphobos/src/std/uni/package.d b/libphobos/src/std/uni/package.d
index 81b949e97f8..c31912a60d0 100644
--- a/libphobos/src/std/uni/package.d
+++ b/libphobos/src/std/uni/package.d
@@ -6271,8 +6271,8 @@ struct UnicodeSetParser(Range)
         {
             if (casefold_)
             {
-                auto range = simpleCaseFoldings(ch);
-                foreach (v; range)
+                auto foldings = simpleCaseFoldings(ch);
+                foreach (v; foldings)
                     set |= v;
             }
             else
diff --git a/libphobos/src/std/utf.d b/libphobos/src/std/utf.d
index 8d94e121ff2..7a0556de822 100644
--- a/libphobos/src/std/utf.d
+++ b/libphobos/src/std/utf.d
@@ -66,7 +66,7 @@ import std.exception : basicExceptionCtors;
 import core.exception : UnicodeException;
 import std.meta : AliasSeq;
 import std.range;
-import std.traits : isAutodecodableString, isConvertibleToString, isPointer,
+import std.traits : isAutodecodableString, isConvertibleToString,
     isSomeChar, isSomeString, isStaticArray, Unqual;
 import std.typecons : Flag, Yes, No;
 
@@ -3136,7 +3136,7 @@ private T toUTFImpl(T, S)(scope S s)
     collection cycle and cause a nasty bug when the C code tries to use it.
   +/
 template toUTFz(P)
-if (isPointer!P && isSomeChar!(typeof(*P.init)))
+if (is(P : C*, C) && isSomeChar!C)
 {
     P toUTFz(S)(S str) @safe pure
     if (isSomeString!S)
diff --git a/libphobos/src/std/windows/registry.d b/libphobos/src/std/windows/registry.d
index d66adff58ca..7ee1f7afc98 100644
--- a/libphobos/src/std/windows/registry.d
+++ b/libphobos/src/std/windows/registry.d
@@ -1856,7 +1856,7 @@ private:
         if (i++ > 0)
             break;
 
-        import core.memory;
+        import core.memory : GC;
         GC.collect();
     }
     assert(i == 2);

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-12-11 16:18 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-12-11 16:18 [gcc r13-4602] d: Merge upstream dmd, druntime c8ae4adb2e, phobos 792c8b7c1 Iain Buclaw

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).