diff mbox series

[committed] d: Merge upstream dmd 6203135dc, druntime e150cca1, phobos a4a18d21c.

Message ID 20220622155846.1041560-1-ibuclaw@gdcproject.org
State New
Headers show
Series [committed] d: Merge upstream dmd 6203135dc, druntime e150cca1, phobos a4a18d21c. | expand

Commit Message

Iain Buclaw June 22, 2022, 3:58 p.m. UTC
Hi,

This patch merges the D front-end with upstream dmd 6203135dc, and the D
run-time library with upstream druntime e150cca1, and phobos a4a18d21c.

D front-end changes:

    - Input parameters can now be applied on extern(C++) functions to
      bind to `const &' when the `-fpreview=in' flag is in effect.

D runtime changes:

    - Run-time flag `--DRT-oncycle=deprecate' has been removed.

Phobos changes:

    - Removed std.experimental.logger's capability to set the minimal
      LogLevel at compile time.

Bootstrapped and regression tested on x86_64-linux-gnu/-m32/-mx32, and
committed to mainline.

Regards,
Iain.

---
gcc/d/ChangeLog:

	* dmd/MERGE: Merge upstream dmd 6203135dc.
	* typeinfo.cc (TypeInfoVisitor::visit (TypeInfoStructDeclaration *)):
	Update for new front-end interface.
	(SpeculativeTypeVisitor::visit (TypeStruct *)): Likewise.

libphobos/ChangeLog:

	* libdruntime/MERGE: Merge upstream druntime e150cca1.
	* src/MERGE: Merge upstream phobos a4a18d21c.
	* testsuite/libphobos.cycles/cycles.exp (cycle_test_list): Update
	expected result of deprecate test.
---
 gcc/d/dmd/MERGE                               |   2 +-
 gcc/d/dmd/aggregate.h                         |  36 +-
 gcc/d/dmd/clone.d                             |   9 +-
 gcc/d/dmd/denum.d                             |  14 +-
 gcc/d/dmd/dstruct.d                           |  33 +-
 gcc/d/dmd/dsymbolsem.d                        |  29 +-
 gcc/d/dmd/enum.h                              |  13 +-
 gcc/d/dmd/escape.d                            |  40 ++-
 gcc/d/dmd/expression.d                        |   2 +-
 gcc/d/dmd/func.d                              |  21 +-
 gcc/d/dmd/parse.d                             |   4 +-
 gcc/d/dmd/statementsem.d                      |  25 +-
 gcc/d/dmd/typesem.d                           |  31 +-
 gcc/d/typeinfo.cc                             |   4 +-
 gcc/testsuite/gdc.test/compilable/b16360.d    |  39 ---
 gcc/testsuite/gdc.test/compilable/inliner.d   |  21 ++
 gcc/testsuite/gdc.test/compilable/inliner2.d  |  27 ++
 .../gdc.test/fail_compilation/fail17927.d     |   8 +-
 .../gdc.test/fail_compilation/fail20108.d     |   2 +-
 .../gdc.test/fail_compilation/fail_scope.d    |   8 +-
 .../gdc.test/fail_compilation/ice12574.d      |   2 +-
 .../gdc.test/fail_compilation/previewin.d     |   2 +-
 .../gdc.test/fail_compilation/previewin2.d    |  18 +
 .../gdc.test/fail_compilation/retscope.d      |  12 +-
 .../gdc.test/fail_compilation/retscope2.d     |   4 +-
 .../gdc.test/fail_compilation/retscope6.d     |  12 +-
 .../gdc.test/fail_compilation/test14238.d     |   2 +-
 .../gdc.test/fail_compilation/test17423.d     |   2 +-
 .../gdc.test/fail_compilation/test17450.d     |   4 +-
 .../gdc.test/fail_compilation/test20245.d     |   8 +-
 .../gdc.test/fail_compilation/test22818.d     |   2 +-
 .../gdc.test/fail_compilation/typeerrors.d    |   2 +-
 .../gdc.test/fail_compilation/udaparams.d     |   4 +-
 .../gdc.test/fail_compilation/udatypes.d      |   8 +
 gcc/testsuite/gdc.test/runnable/ice10086b.d   |  50 +++
 gcc/testsuite/gdc.test/runnable/inline3.d     |  44 +++
 .../gdc.test/runnable/staticforeach.d         |  29 ++
 gcc/testsuite/gdc.test/runnable_cxx/cppa.d    |  20 +-
 .../runnable_cxx/extra-files/cppb.cpp         |  30 +-
 libphobos/libdruntime/MERGE                   |   2 +-
 libphobos/libdruntime/core/stdc/config.d      |  31 ++
 libphobos/libdruntime/core/stdc/errno.d       | 137 ++++++++
 libphobos/libdruntime/core/stdc/stdarg.d      |  21 ++
 libphobos/libdruntime/core/stdc/stddef.d      |   5 +
 libphobos/libdruntime/core/stdc/stdint.d      |  35 ++
 libphobos/libdruntime/core/stdc/stdio.d       |  72 ++++
 libphobos/libdruntime/core/stdc/stdlib.d      |   1 +
 libphobos/libdruntime/core/sys/elf/package.d  |  63 ++++
 libphobos/libdruntime/core/sys/posix/fcntl.d  |   6 +
 .../libdruntime/core/sys/windows/winsock2.d   |  14 +-
 libphobos/libdruntime/core/thread/osthread.d  |   4 +-
 .../libdruntime/core/thread/threadbase.d      |  12 +-
 libphobos/libdruntime/core/time.d             |   4 +-
 libphobos/libdruntime/core/vararg.d           |  17 +
 libphobos/libdruntime/rt/critical_.d          |   4 +-
 libphobos/libdruntime/rt/dmain2.d             |  16 +-
 libphobos/libdruntime/rt/lifetime.d           |   6 +-
 libphobos/libdruntime/rt/minfo.d              | 216 +-----------
 libphobos/libdruntime/rt/monitor_.d           |   6 +-
 libphobos/src/MERGE                           |   2 +-
 libphobos/src/std/complex.d                   |   2 +-
 libphobos/src/std/experimental/logger/core.d  | 329 +++---------------
 .../src/std/experimental/logger/package.d     |  20 --
 libphobos/src/std/file.d                      |  30 +-
 libphobos/src/std/math/algebraic.d            |   6 +-
 libphobos/src/std/math/hardware.d             |   6 +-
 libphobos/src/std/math/trigonometry.d         |  46 +--
 libphobos/src/std/numeric.d                   |  44 ++-
 libphobos/src/std/stdio.d                     |  12 +-
 libphobos/src/std/sumtype.d                   |  50 ++-
 .../testsuite/libphobos.cycles/cycles.exp     |   2 +-
 71 files changed, 1071 insertions(+), 773 deletions(-)
 delete mode 100644 gcc/testsuite/gdc.test/compilable/b16360.d
 create mode 100644 gcc/testsuite/gdc.test/compilable/inliner.d
 create mode 100644 gcc/testsuite/gdc.test/compilable/inliner2.d
 create mode 100644 gcc/testsuite/gdc.test/fail_compilation/previewin2.d
 create mode 100644 gcc/testsuite/gdc.test/fail_compilation/udatypes.d
 create mode 100644 gcc/testsuite/gdc.test/runnable/inline3.d
diff mbox series

Patch

diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE
index d39658a808e..d1e3dc16312 100644
--- a/gcc/d/dmd/MERGE
+++ b/gcc/d/dmd/MERGE
@@ -1,4 +1,4 @@ 
-821ed393d428c7db5a48623e77d43f5647d5c6a2
+6203135dcf0112d3211add0cbfb22fecc5df1af4
 
 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.h b/gcc/d/dmd/aggregate.h
index f27ca0769c9..d91e35ee8c2 100644
--- a/gcc/d/dmd/aggregate.h
+++ b/gcc/d/dmd/aggregate.h
@@ -159,17 +159,6 @@  struct StructFlags
 class StructDeclaration : public AggregateDeclaration
 {
 public:
-    bool zeroInit;              // !=0 if initialize with 0 fill
-    bool hasIdentityAssign;     // true if has identity opAssign
-    bool hasBlitAssign;         // true if opAssign is a blit
-    bool hasIdentityEquals;     // true if has identity opEquals
-    bool hasNoFields;           // has no fields
-    bool hasCopyCtor;           // copy constructor
-    // Even if struct is defined as non-root symbol, some built-in operations
-    // (e.g. TypeidExp, NewExp, ArrayLiteralExp, etc) request its TypeInfo.
-    // For those, today TypeInfo_Struct is generated in COMDAT.
-    bool requestTypeInfo;
-
     FuncDeclarations postblits; // Array of postblit functions
     FuncDeclaration *postblit;  // aggregate postblit
 
@@ -179,18 +168,37 @@  public:
     static FuncDeclaration *xerreq;      // object.xopEquals
     static FuncDeclaration *xerrcmp;     // object.xopCmp
 
-    structalign_t alignment;    // alignment applied outside of the struct
-    ThreeState ispod;           // if struct is POD
-
     // ABI-specific type(s) if the struct can be passed in registers
     TypeTuple *argTypes;
 
+    structalign_t alignment;    // alignment applied outside of the struct
+    ThreeState ispod;           // if struct is POD
+private:
+    uint8_t bitFields;
+public:
     static StructDeclaration *create(const Loc &loc, Identifier *id, bool inObject);
     StructDeclaration *syntaxCopy(Dsymbol *s) override;
     Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly) override final;
     const char *kind() const override;
     void finalizeSize() override final;
     bool isPOD();
+    bool zeroInit() const;          // !=0 if initialize with 0 fill
+    bool zeroInit(bool v);
+    bool hasIdentityAssign() const; // true if has identity opAssign
+    bool hasIdentityAssign(bool v);
+    bool hasBlitAssign() const;     // true if opAssign is a blit
+    bool hasBlitAssign(bool v);
+    bool hasIdentityEquals() const; // true if has identity opEquals
+    bool hasIdentityEquals(bool v);
+    bool hasNoFields() const;       // has no fields
+    bool hasNoFields(bool v);
+    bool hasCopyCtor() const;       // copy constructor
+    bool hasCopyCtor(bool v);
+    // Even if struct is defined as non-root symbol, some built-in operations
+    // (e.g. TypeidExp, NewExp, ArrayLiteralExp, etc) request its TypeInfo.
+    // For those, today TypeInfo_Struct is generated in COMDAT.
+    bool requestTypeInfo() const;
+    bool requestTypeInfo(bool v);
 
     StructDeclaration *isStructDeclaration() override final { return this; }
     void accept(Visitor *v) override { v->visit(this); }
diff --git a/gcc/d/dmd/clone.d b/gcc/d/dmd/clone.d
index 75a16bd2da4..cf4ccbb955c 100644
--- a/gcc/d/dmd/clone.d
+++ b/gcc/d/dmd/clone.d
@@ -404,7 +404,12 @@  bool needOpEquals(StructDeclaration sd)
 {
     //printf("StructDeclaration::needOpEquals() %s\n", sd.toChars());
     if (sd.isUnionDeclaration())
-        goto Ldontneed;
+    {
+        /* If a union has only one field, treat it like a struct
+         */
+        if (sd.fields.length != 1)
+            goto Ldontneed;
+    }
     if (sd.hasIdentityEquals)
         goto Lneed;
     /* If any of the fields has an opEquals, then we
@@ -421,7 +426,7 @@  bool needOpEquals(StructDeclaration sd)
         if (tvbase.ty == Tstruct)
         {
             TypeStruct ts = cast(TypeStruct)tvbase;
-            if (ts.sym.isUnionDeclaration())
+            if (ts.sym.isUnionDeclaration() && ts.sym.fields.length != 1)
                 continue;
             if (needOpEquals(ts.sym))
                 goto Lneed;
diff --git a/gcc/d/dmd/denum.d b/gcc/d/dmd/denum.d
index aba290bed05..ef322f13da5 100644
--- a/gcc/d/dmd/denum.d
+++ b/gcc/d/dmd/denum.d
@@ -54,9 +54,17 @@  extern (C++) final class EnumDeclaration : ScopeDsymbol
     Expression maxval;
     Expression minval;
     Expression defaultval;  // default initializer
-    bool isdeprecated;
-    bool added;
-    int inuse;
+
+    // `bool` fields that are compacted into bit fields in a string mixin
+    private extern (D) static struct BitFields
+    {
+        bool isdeprecated;
+        bool added;
+        bool inuse;
+    }
+
+    import dmd.common.bitfields : generateBitFields;
+    mixin(generateBitFields!(BitFields, ubyte));
 
     extern (D) this(const ref Loc loc, Identifier ident, Type memtype)
     {
diff --git a/gcc/d/dmd/dstruct.d b/gcc/d/dmd/dstruct.d
index de5f1453c9a..4126a8adc68 100644
--- a/gcc/d/dmd/dstruct.d
+++ b/gcc/d/dmd/dstruct.d
@@ -192,17 +192,6 @@  enum StructFlags : int
  */
 extern (C++) class StructDeclaration : AggregateDeclaration
 {
-    bool zeroInit;              // !=0 if initialize with 0 fill
-    bool hasIdentityAssign;     // true if has identity opAssign
-    bool hasBlitAssign;         // true if opAssign is a blit
-    bool hasIdentityEquals;     // true if has identity opEquals
-    bool hasNoFields;           // has no fields
-    bool hasCopyCtor;           // copy constructor
-    // Even if struct is defined as non-root symbol, some built-in operations
-    // (e.g. TypeidExp, NewExp, ArrayLiteralExp, etc) request its TypeInfo.
-    // For those, today TypeInfo_Struct is generated in COMDAT.
-    bool requestTypeInfo;
-
     FuncDeclarations postblits; // Array of postblit functions
     FuncDeclaration postblit;   // aggregate postblit
 
@@ -212,11 +201,29 @@  extern (C++) class StructDeclaration : AggregateDeclaration
     extern (C++) __gshared FuncDeclaration xerreq;   // object.xopEquals
     extern (C++) __gshared FuncDeclaration xerrcmp;  // object.xopCmp
 
+    // ABI-specific type(s) if the struct can be passed in registers
+    TypeTuple argTypes;
+
     structalign_t alignment;    // alignment applied outside of the struct
     ThreeState ispod;           // if struct is POD
 
-    // ABI-specific type(s) if the struct can be passed in registers
-    TypeTuple argTypes;
+    // `bool` fields that are compacted into bit fields in a string mixin
+    private extern (D) static struct BitFields
+    {
+        bool zeroInit;              // !=0 if initialize with 0 fill
+        bool hasIdentityAssign;     // true if has identity opAssign
+        bool hasBlitAssign;         // true if opAssign is a blit
+        bool hasIdentityEquals;     // true if has identity opEquals
+        bool hasNoFields;           // has no fields
+        bool hasCopyCtor;           // copy constructor
+        // Even if struct is defined as non-root symbol, some built-in operations
+        // (e.g. TypeidExp, NewExp, ArrayLiteralExp, etc) request its TypeInfo.
+        // For those, today TypeInfo_Struct is generated in COMDAT.
+        bool requestTypeInfo;
+    }
+
+    import dmd.common.bitfields : generateBitFields;
+    mixin(generateBitFields!(BitFields, ubyte));
 
     extern (D) this(const ref Loc loc, Identifier id, bool inObject)
     {
diff --git a/gcc/d/dmd/dsymbolsem.d b/gcc/d/dmd/dsymbolsem.d
index 6dbc129baaf..7fd47818759 100644
--- a/gcc/d/dmd/dsymbolsem.d
+++ b/gcc/d/dmd/dsymbolsem.d
@@ -49,6 +49,7 @@  import dmd.identifier;
 import dmd.importc;
 import dmd.init;
 import dmd.initsem;
+import dmd.intrange;
 import dmd.hdrgen;
 import dmd.mtype;
 import dmd.mustuse;
@@ -2177,6 +2178,13 @@  private extern(C++) final class DsymbolSemanticVisitor : Visitor
             assert(ed.memtype);
             int nextValue = 0;        // C11 6.7.2.2-3 first member value defaults to 0
 
+            // C11 6.7.2.2-2 value must be representable as an int.
+            // The sizemask represents all values that int will fit into,
+            // from 0..uint.max.  We want to cover int.min..uint.max.
+            const mask = Type.tint32.sizemask();
+            IntRange ir = IntRange(SignExtendedNumber(~(mask >> 1), true),
+                                   SignExtendedNumber(mask));
+
             void emSemantic(EnumMember em, ref int nextValue)
             {
                 static void errorReturn(EnumMember em)
@@ -2206,21 +2214,32 @@  private extern(C++) final class DsymbolSemanticVisitor : Visitor
                         em.error("enum member must be an integral constant expression, not `%s` of type `%s`", e.toChars(), e.type.toChars());
                         return errorReturn(em);
                     }
-                    const sinteger_t v = ie.toInteger();
-                    if (v < int.min || v > uint.max)
+                    if (!ir.contains(getIntRange(ie)))
                     {
                         // C11 6.7.2.2-2
                         em.error("enum member value `%s` does not fit in an `int`", e.toChars());
                         return errorReturn(em);
                     }
-                    em.value = new IntegerExp(em.loc, cast(int)v, Type.tint32);
-                    nextValue = cast(int)v;
+                    nextValue = cast(int)ie.toInteger();
+                    em.value = new IntegerExp(em.loc, nextValue, Type.tint32);
                 }
                 else
                 {
+                    // C11 6.7.2.2-3 add 1 to value of previous enumeration constant
+                    bool first = (em == (*em.ed.members)[0]);
+                    if (!first)
+                    {
+                        import core.checkedint : adds;
+                        bool overflow;
+                        nextValue = adds(nextValue, 1, overflow);
+                        if (overflow)
+                        {
+                            em.error("initialization with `%d+1` causes overflow for type `int`", nextValue - 1);
+                            return errorReturn(em);
+                        }
+                    }
                     em.value = new IntegerExp(em.loc, nextValue, Type.tint32);
                 }
-                ++nextValue; // C11 6.7.2.2-3 add 1 to value of previous enumeration constant
                 em.semanticRun = PASS.semanticdone;
             }
 
diff --git a/gcc/d/dmd/enum.h b/gcc/d/dmd/enum.h
index 9ec130099fe..723cebc7e0a 100644
--- a/gcc/d/dmd/enum.h
+++ b/gcc/d/dmd/enum.h
@@ -35,10 +35,15 @@  public:
     Expression *maxval;
     Expression *minval;
     Expression *defaultval;     // default initializer
-
-    bool isdeprecated;
-    bool added;
-    int inuse;
+private:
+    uint8_t bitFields;
+public:
+    bool isdeprecated() const;
+    bool isdeprecated(bool v);
+    bool added() const;
+    bool added(bool v);
+    bool inuse() const;
+    bool inuse(bool v);
 
     EnumDeclaration *syntaxCopy(Dsymbol *s) override;
     void addMember(Scope *sc, ScopeDsymbol *sds) override;
diff --git a/gcc/d/dmd/escape.d b/gcc/d/dmd/escape.d
index 97a655289b5..0646f57c5cd 100644
--- a/gcc/d/dmd/escape.d
+++ b/gcc/d/dmd/escape.d
@@ -328,12 +328,12 @@  bool checkParamArgumentEscape(Scope* sc, FuncDeclaration fdc, Parameter par, STC
         else if (par)
         {
             result |= sc.setUnsafeDIP1000(gag, arg.loc,
-                desc ~ " `%s` assigned to non-scope parameter `%s`", v, par);
+                desc ~ " `%s` assigned to non-scope parameter `%s` calling `%s`", v, par, fdc);
         }
         else
         {
             result |= sc.setUnsafeDIP1000(gag, arg.loc,
-                desc ~ " `%s` assigned to non-scope parameter `this`", v);
+                desc ~ " `%s` assigned to non-scope parameter `this` calling `%s`", v, fdc);
         }
     }
 
@@ -1230,9 +1230,24 @@  private bool checkReturnEscapeImpl(Scope* sc, Expression e, bool refs, bool gag)
                 !(!refs && sc.func.isFuncDeclaration().getLevel(pfunc, sc.intypeof) > 0)
                )
             {
-                // https://issues.dlang.org/show_bug.cgi?id=17029
-                result |= sc.setUnsafeDIP1000(gag, e.loc, "scope variable `%s` may not be returned", v);
-                continue;
+                if (v.isParameter() && !(v.storage_class & STC.return_))
+                {
+                    // https://issues.dlang.org/show_bug.cgi?id=23191
+                    if (!gag)
+                    {
+                        previewErrorFunc(sc.isDeprecated(), global.params.useDIP1000)(e.loc,
+                            "scope parameter `%s` may not be returned", v.toChars()
+                        );
+                        result = true;
+                        continue;
+                    }
+                }
+                else
+                {
+                    // https://issues.dlang.org/show_bug.cgi?id=17029
+                    result |= sc.setUnsafeDIP1000(gag, e.loc, "scope variable `%s` may not be returned", v);
+                    continue;
+                }
             }
         }
         else if (v.storage_class & STC.variadic && p == sc.func)
@@ -2492,9 +2507,11 @@  private void addMaybe(VarDeclaration va, VarDeclaration v)
  *   fmt = printf-style format string
  *   arg0  = (optional) argument for first %s format specifier
  *   arg1  = (optional) argument for second %s format specifier
+ *   arg2  = (optional) argument for third %s format specifier
  * Returns: whether an actual safe error (not deprecation) occured
  */
-private bool setUnsafePreview(Scope* sc, FeatureState fs, bool gag, Loc loc, const(char)* msg, RootObject arg0 = null, RootObject arg1 = null)
+private bool setUnsafePreview(Scope* sc, FeatureState fs, bool gag, Loc loc, const(char)* msg,
+    RootObject arg0 = null, RootObject arg1 = null, RootObject arg2 = null)
 {
     if (fs == FeatureState.disabled)
     {
@@ -2502,7 +2519,7 @@  private bool setUnsafePreview(Scope* sc, FeatureState fs, bool gag, Loc loc, con
     }
     else if (fs == FeatureState.enabled)
     {
-        return sc.setUnsafe(gag, loc, msg, arg0, arg1);
+        return sc.setUnsafe(gag, loc, msg, arg0, arg1, arg2);
     }
     else
     {
@@ -2510,22 +2527,23 @@  private bool setUnsafePreview(Scope* sc, FeatureState fs, bool gag, Loc loc, con
         {
             if (!gag)
                 previewErrorFunc(sc.isDeprecated(), fs)(
-                    loc, msg, arg0 ? arg0.toChars() : "", arg1 ? arg1.toChars() : ""
+                    loc, msg, arg0 ? arg0.toChars() : "", arg1 ? arg1.toChars() : "", arg2 ? arg2.toChars() : ""
                 );
         }
         else if (!sc.func.safetyViolation)
         {
             import dmd.func : AttributeViolation;
-            sc.func.safetyViolation = new AttributeViolation(loc, msg, arg0, arg1);
+            sc.func.safetyViolation = new AttributeViolation(loc, msg, arg0, arg1, arg2);
         }
         return false;
     }
 }
 
 // `setUnsafePreview` partially evaluated for dip1000
-private bool setUnsafeDIP1000(Scope* sc, bool gag, Loc loc, const(char)* msg, RootObject arg0 = null, RootObject arg1 = null)
+private bool setUnsafeDIP1000(Scope* sc, bool gag, Loc loc, const(char)* msg,
+    RootObject arg0 = null, RootObject arg1 = null, RootObject arg2 = null)
 {
-    return setUnsafePreview(sc, global.params.useDIP1000, gag, loc, msg, arg0, arg1);
+    return setUnsafePreview(sc, global.params.useDIP1000, gag, loc, msg, arg0, arg1, arg2);
 }
 
 /***************************************
diff --git a/gcc/d/dmd/expression.d b/gcc/d/dmd/expression.d
index 4d171059306..ceecf4b5e74 100644
--- a/gcc/d/dmd/expression.d
+++ b/gcc/d/dmd/expression.d
@@ -1438,7 +1438,7 @@  extern (C++) abstract class Expression : ASTNode
             else if (!sc.func.safetyViolation)
             {
                 import dmd.func : AttributeViolation;
-                sc.func.safetyViolation = new AttributeViolation(this.loc, null, f, null);
+                sc.func.safetyViolation = new AttributeViolation(this.loc, null, f, null, null);
             }
         }
         return false;
diff --git a/gcc/d/dmd/func.d b/gcc/d/dmd/func.d
index d42925990a9..83bc2eab1fe 100644
--- a/gcc/d/dmd/func.d
+++ b/gcc/d/dmd/func.d
@@ -1476,17 +1476,19 @@  extern (C++) class FuncDeclaration : Declaration
      *   fmt = printf-style format string
      *   arg0  = (optional) argument for first %s format specifier
      *   arg1  = (optional) argument for second %s format specifier
+     *   arg2  = (optional) argument for third %s format specifier
      * Returns: whether there's a safe error
      */
     extern (D) final bool setUnsafe(
-        bool gag = false, Loc loc = Loc.init, const(char)* fmt = null, RootObject arg0 = null, RootObject arg1 = null)
+        bool gag = false, Loc loc = Loc.init, const(char)* fmt = null,
+        RootObject arg0 = null, RootObject arg1 = null, RootObject arg2 = null)
     {
         if (flags & FUNCFLAG.safetyInprocess)
         {
             flags &= ~FUNCFLAG.safetyInprocess;
             type.toTypeFunction().trust = TRUST.system;
             if (fmt || arg0)
-                safetyViolation = new AttributeViolation(loc, fmt, arg0, arg1);
+                safetyViolation = new AttributeViolation(loc, fmt, arg0, arg1, arg2);
 
             if (fes)
                 fes.func.setUnsafe();
@@ -1494,7 +1496,7 @@  extern (C++) class FuncDeclaration : Declaration
         else if (isSafe())
         {
             if (!gag && fmt)
-                .error(loc, fmt, arg0 ? arg0.toChars() : "", arg1 ? arg1.toChars() : "");
+                .error(loc, fmt, arg0 ? arg0.toChars() : "", arg1 ? arg1.toChars() : "", arg2 ? arg2.toChars() : "");
 
             return true;
         }
@@ -4370,10 +4372,12 @@  extern (C++) final class NewDeclaration : FuncDeclaration
  *   fmt = printf-style format string
  *   arg0  = (optional) argument for first %s format specifier
  *   arg1  = (optional) argument for second %s format specifier
+ *   arg2  = (optional) argument for third %s format specifier
  * Returns: whether there's a safe error
  */
 bool setUnsafe(Scope* sc,
-    bool gag = false, Loc loc = Loc.init, const(char)* fmt = null, RootObject arg0 = null, RootObject arg1 = null)
+    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
@@ -4394,13 +4398,13 @@  bool setUnsafe(Scope* sc,
         {
             // Message wil be gagged, but still call error() to update global.errors and for
             // -verrors=spec
-            .error(loc, fmt, arg0 ? arg0.toChars() : "", arg1 ? arg1.toChars() : "");
+            .error(loc, fmt, arg0 ? arg0.toChars() : "", arg1 ? arg1.toChars() : "", arg2 ? arg2.toChars() : "");
             return true;
         }
         return false;
     }
 
-    return sc.func.setUnsafe(gag, loc, fmt, arg0, arg1);
+    return sc.func.setUnsafe(gag, loc, fmt, arg0, arg1, arg2);
 }
 
 /// Stores a reason why a function failed to infer a function attribute like `@safe` or `pure`
@@ -4421,6 +4425,8 @@  struct AttributeViolation
     RootObject arg0 = null;
     /// ditto
     RootObject arg1 = null;
+    /// ditto
+    RootObject arg2 = null;
 }
 
 /// Print the reason why `fd` was inferred `@system` as a supplemental error
@@ -4438,7 +4444,8 @@  void errorSupplementalInferredSafety(FuncDeclaration fd, int maxDepth, bool depr
             errorFunc(s.loc, deprecation ?
                 "which would be `@system` because of:" :
                 "which was inferred `@system` because of:");
-            errorFunc(s.loc, s.fmtStr, s.arg0 ? s.arg0.toChars() : "", s.arg1 ? s.arg1.toChars() : "");
+            errorFunc(s.loc, s.fmtStr,
+                s.arg0 ? s.arg0.toChars() : "", s.arg1 ? s.arg1.toChars() : "", s.arg2 ? s.arg2.toChars() : "");
         }
         else if (FuncDeclaration fd2 = cast(FuncDeclaration) s.arg0)
         {
diff --git a/gcc/d/dmd/parse.d b/gcc/d/dmd/parse.d
index 89f8ae3470f..eb5e6942948 100644
--- a/gcc/d/dmd/parse.d
+++ b/gcc/d/dmd/parse.d
@@ -4862,7 +4862,7 @@  class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
                     if (udas !is null)
                     {
                         if (storage_class != 0)
-                            error("cannot put a storage-class in an alias declaration.");
+                            error("cannot put a storage-class in an `alias` declaration.");
                         // parseAttributes shouldn't have set these variables
                         assert(link == linkage && !setAlignment && ealign is null);
                         auto tpl_ = cast(AST.TemplateDeclaration) s;
@@ -4887,7 +4887,7 @@  class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
                     parseAttributes();
                     // type
                     if (udas)
-                        error("user-defined attributes not allowed for alias declarations");
+                        error("user-defined attributes not allowed for `alias` declarations");
 
                     auto t = parseType();
 
diff --git a/gcc/d/dmd/statementsem.d b/gcc/d/dmd/statementsem.d
index 06e28a4819d..f23b9882ae0 100644
--- a/gcc/d/dmd/statementsem.d
+++ b/gcc/d/dmd/statementsem.d
@@ -4401,19 +4401,21 @@  public auto makeTupleForeach(Scope* sc, bool isStatic, bool isDecl, ForeachState
                 Dsymbol ds = null;
                 if (!(storageClass & STC.manifest))
                 {
-                    if ((isStatic || tb.ty == Tfunction || storageClass&STC.alias_) && e.op == EXP.variable)
-                        ds = (cast(VarExp)e).var;
-                    else if (e.op == EXP.template_)
-                        ds = (cast(TemplateExp)e).td;
-                    else if (e.op == EXP.scope_)
-                        ds = (cast(ScopeExp)e).sds;
-                    else if (e.op == EXP.function_)
+                    if (isStatic || tb.ty == Tfunction || storageClass & STC.alias_)
                     {
-                        auto fe = cast(FuncExp)e;
-                        ds = fe.td ? cast(Dsymbol)fe.td : fe.fd;
+                        if (auto ve = e.isVarExp())
+                            ds = ve.var;
+                        else if (auto dve = e.isDotVarExp())
+                            ds = dve.var;
                     }
-                    else if (e.op == EXP.overloadSet)
-                        ds = (cast(OverExp)e).vars;
+                    if (auto te = e.isTemplateExp())
+                        ds = te.td;
+                    else if (auto se = e.isScopeExp())
+                        ds = se.sds;
+                    else if (auto fe = e.isFuncExp())
+                        ds = fe.td ? fe.td : fe.fd;
+                    else if (auto oe = e.isOverExp())
+                        ds = oe.vars;
                 }
                 else if (storageClass & STC.alias_)
                 {
@@ -4530,6 +4532,7 @@  public auto makeTupleForeach(Scope* sc, bool isStatic, bool isDecl, ForeachState
                 auto field = Identifier.idPool(StaticForeach.tupleFieldName.ptr,StaticForeach.tupleFieldName.length);
                 Expression access = new DotIdExp(loc, e, field);
                 access = expressionSemantic(access, sc);
+                access = access.optimize(WANTvalue);
                 if (!tuple) return returnEarly();
                 //printf("%s\n",tuple.toChars());
                 foreach (l; 0 .. dim)
diff --git a/gcc/d/dmd/typesem.d b/gcc/d/dmd/typesem.d
index 31ecbd246e6..8cacdb10a26 100644
--- a/gcc/d/dmd/typesem.d
+++ b/gcc/d/dmd/typesem.d
@@ -119,7 +119,7 @@  private void resolveTupleIndex(const ref Loc loc, Scope* sc, Dsymbol s, out Expr
     const(uinteger_t) d = eindex.toUInteger();
     if (d >= tup.objects.dim)
     {
-        .error(loc, "tuple index `%llu` exceeds length %llu", d, cast(ulong)tup.objects.dim);
+        .error(loc, "tuple index `%llu` out of bounds `[0 .. %llu]`", d, cast(ulong)tup.objects.dim);
         pt = Type.terror;
         return;
     }
@@ -554,7 +554,7 @@  extern(C++) Type typeSemantic(Type type, const ref Loc loc, Scope* sc)
             uinteger_t d = mtype.dim.toUInteger();
             if (d >= tup.objects.dim)
             {
-                .error(loc, "tuple index %llu exceeds %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.dim);
                 return error();
             }
 
@@ -649,7 +649,7 @@  extern(C++) Type typeSemantic(Type type, const ref Loc loc, Scope* sc)
                 uinteger_t d = mtype.dim.toUInteger();
                 if (d >= tt.arguments.dim)
                 {
-                    .error(loc, "tuple index %llu exceeds %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.dim);
                     return error();
                 }
                 Type telem = (*tt.arguments)[cast(size_t)d].type;
@@ -1224,6 +1224,25 @@  extern(C++) Type typeSemantic(Type type, const ref Loc loc, Scope* sc)
                     continue;
                 }
 
+                // -preview=in: Always add `ref` when used with `extern(C++)` functions
+                // Done here to allow passing opaque types with `in`
+                if (global.params.previewIn && (fparam.storageClass & (STC.in_ | STC.ref_)) == STC.in_)
+                {
+                    switch (tf.linkage)
+                    {
+                    case LINK.cpp:
+                        fparam.storageClass |= STC.ref_;
+                        break;
+                    case LINK.default_, LINK.d:
+                        break;
+                    default:
+                        .error(loc, "cannot use `in` parameters with `extern(%s)` functions",
+                               linkageToChars(tf.linkage));
+                        .errorSupplemental(loc, "parameter `%s` declared as `in` here", fparam.toChars());
+                        break;
+                    }
+                }
+
                 if (t.ty == Tfunction)
                 {
                     .error(loc, "cannot have parameter of function type `%s`", fparam.type.toChars());
@@ -2572,7 +2591,7 @@  void resolve(Type mt, const ref Loc loc, Scope* sc, out Expression pe, out Type
                 const d = mt.dim.toUInteger();
                 if (d >= tup.objects.dim)
                 {
-                    error(loc, "tuple index `%llu` exceeds length %llu", d, cast(ulong) tup.objects.dim);
+                    error(loc, "tuple index `%llu` out of bounds `[0 .. %llu]`", d, cast(ulong) tup.objects.dim);
                     return returnError();
                 }
 
@@ -4891,9 +4910,9 @@  Expression getMaxMinValue(EnumDeclaration ed, const ref Loc loc, Identifier id)
              */
             Expression e = em.value;
             Expression ec = new CmpExp(id == Id.max ? EXP.greaterThan : EXP.lessThan, em.loc, e, *pval);
-            ed.inuse++;
+            ed.inuse = true;
             ec = ec.expressionSemantic(em._scope);
-            ed.inuse--;
+            ed.inuse = false;
             ec = ec.ctfeInterpret();
             if (ec.op == EXP.error)
             {
diff --git a/gcc/d/typeinfo.cc b/gcc/d/typeinfo.cc
index 1f8afdd2c74..d1f0d59952f 100644
--- a/gcc/d/typeinfo.cc
+++ b/gcc/d/typeinfo.cc
@@ -1050,7 +1050,7 @@  public:
     this->layout_string (ti->deco);
 
     /* Default initializer for struct.  */
-    tree ptr = (sd->zeroInit) ? null_pointer_node
+    tree ptr = (sd->zeroInit ()) ? null_pointer_node
       : build_address (aggregate_initializer_decl (sd));
     this->layout_field (d_array_value (array_type_node,
 				       size_int (sd->structsize), ptr));
@@ -1771,7 +1771,7 @@  public:
       {
 	if (!ti->needsCodegen ())
 	  {
-	    if (ti->minst || sd->requestTypeInfo)
+	    if (ti->minst || sd->requestTypeInfo ())
 	      return;
 
 	    this->result_ |= true;
diff --git a/gcc/testsuite/gdc.test/compilable/b16360.d b/gcc/testsuite/gdc.test/compilable/b16360.d
deleted file mode 100644
index 11415791b65..00000000000
--- a/gcc/testsuite/gdc.test/compilable/b16360.d
+++ /dev/null
@@ -1,39 +0,0 @@ 
-/*
-REQUIRED_ARGS: -inline -wi
-
-TEST_OUTPUT:
----
-compilable/b16360.d(12): Warning: cannot inline function `b16360.foo`
-compilable/b16360.d(25): Warning: cannot inline function `b16360.bar`
----
-*/
-
-pragma(inline, true)
-auto foo()
-{
-    static struct U
-    {
-        int a = 42;
-        float b;
-        ~this(){} // __dtor: inline not allowed
-    }
-    U u;
-    return u.a;
-}
-
-pragma(inline, true)
-auto bar()
-{
-    class U   // class : inline not allowed
-    {
-        int a = 42;
-        float b;
-    }
-    return (new U).a;
-}
-
-void main()
-{
-    auto f = foo();
-    auto b = bar();
-}
diff --git a/gcc/testsuite/gdc.test/compilable/inliner.d b/gcc/testsuite/gdc.test/compilable/inliner.d
new file mode 100644
index 00000000000..1273809b8db
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/inliner.d
@@ -0,0 +1,21 @@ 
+// REQUIRED_ARGS: -inline -O -unittest
+
+struct Cent
+{
+    ulong lo;
+    ulong hi;
+}
+
+Cent add(Cent, Cent);
+
+Cent sub(Cent c1, Cent c2)
+{
+    return add(c1, c2);
+}
+
+Cent udivmod(Cent c3, Cent c4)
+{
+    Cent quotient;
+    Cent rem = sub(c3, c4);
+    return quotient;
+}
diff --git a/gcc/testsuite/gdc.test/compilable/inliner2.d b/gcc/testsuite/gdc.test/compilable/inliner2.d
new file mode 100644
index 00000000000..7ffa5cca31b
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/inliner2.d
@@ -0,0 +1,27 @@ 
+// REQUIRED_ARGS: -O -inline
+
+struct Cent
+{
+    ulong lo;  // low 64 bits
+    ulong hi;  // high 64 bits
+}
+
+pure bool tst(Cent c)
+{
+    return c.hi || c.lo;
+}
+
+pure Cent dec(Cent c);
+pure Cent shl(Cent c, uint n);
+
+pure Cent udivmod(Cent c1, Cent c2, out Cent modulus)
+{
+    ulong v1 = shl(c2, 3).hi;
+
+    Cent quotient;
+
+    if (tst(quotient))
+        quotient = dec(quotient);
+
+    return quotient;
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail17927.d b/gcc/testsuite/gdc.test/fail_compilation/fail17927.d
index 410f3077706..cf610ff8d97 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail17927.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail17927.d
@@ -1,10 +1,10 @@ 
 /* REQUIRED_ARGS: -preview=dip1000
  * TEST_OUTPUT:
 ---
-fail_compilation/fail17927.d(13): Error: scope variable `this` may not be returned
-fail_compilation/fail17927.d(15): Error: scope variable `this` may not be returned
-fail_compilation/fail17927.d(21): Error: scope variable `ptr` may not be returned
-fail_compilation/fail17927.d(23): Error: scope variable `ptr` may not be returned
+fail_compilation/fail17927.d(13): Error: scope parameter `this` may not be returned
+fail_compilation/fail17927.d(15): Error: scope parameter `this` may not be returned
+fail_compilation/fail17927.d(21): Error: scope parameter `ptr` may not be returned
+fail_compilation/fail17927.d(23): Error: scope parameter `ptr` may not be returned
 ---
 */
 // https://issues.dlang.org/show_bug.cgi?id=17927
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail20108.d b/gcc/testsuite/gdc.test/fail_compilation/fail20108.d
index f768b89e6a4..15845e1d2fc 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail20108.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail20108.d
@@ -3,7 +3,7 @@ 
 TEST_OUTPUT:
 ---
 fail_compilation/fail20108.d(15): Error: address of variable `y` assigned to `x` with longer lifetime
-fail_compilation/fail20108.d(16): Error: scope variable `x` may not be returned
+fail_compilation/fail20108.d(16): Error: scope parameter `x` may not be returned
 fail_compilation/fail20108.d(23): Error: address of variable `y` assigned to `x` with longer lifetime
 fail_compilation/fail20108.d(24): Error: scope variable `x` may not be returned
 ---
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail_scope.d b/gcc/testsuite/gdc.test/fail_compilation/fail_scope.d
index 3e7637ff667..3fac1678e69 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail_scope.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail_scope.d
@@ -2,7 +2,10 @@ 
 REQUIRED_ARGS:
 TEST_OUTPUT:
 ---
-fail_compilation/fail_scope.d(40): Deprecation: scope variable `p` may not be returned
+fail_compilation/fail_scope.d(30): Deprecation: scope parameter `da` may not be returned
+fail_compilation/fail_scope.d(32): Deprecation: scope parameter `o` may not be returned
+fail_compilation/fail_scope.d(33): Deprecation: scope parameter `dg` may not be returned
+fail_compilation/fail_scope.d(40): Deprecation: scope parameter `p` may not be returned
 fail_compilation/fail_scope.d(45): Error: returning `cast(char[])string` escapes a reference to local variable `string`
 fail_compilation/fail_scope.d(63): Error: returning `s.bar()` escapes a reference to local variable `s`
 fail_compilation/fail_scope.d(74): Error: `fail_scope.foo8` called with argument types `(int)` matches both:
@@ -16,9 +19,6 @@  fail_compilation/fail_scope.d(108): Deprecation: escaping reference to outer loc
 fail_compilation/fail_scope.d(127): Deprecation: returning `s.bar()` escapes a reference to local variable `s`
 fail_compilation/fail_scope.d(137): Error: returning `foo16226(i)` escapes a reference to local variable `i`
 ---
-//fail_compilation/fail_scope.d(30): Error: scope variable `da` may not be returned
-//fail_compilation/fail_scope.d(32): Error: scope variable `o` may not be returned
-//fail_compilation/fail_scope.d(33): Error: scope variable `dg` may not be returned
 //fail_compilation/fail_scope.d(35): Error: scope variable `da` may not be returned
 //fail_compilation/fail_scope.d(37): Error: scope variable `o` may not be returned
 //fail_compilation/fail_scope.d(38): Error: scope variable `dg` may not be returned
diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice12574.d b/gcc/testsuite/gdc.test/fail_compilation/ice12574.d
index 420b6b70078..93e5f1d8cc0 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/ice12574.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/ice12574.d
@@ -1,7 +1,7 @@ 
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/ice12574.d(40): Error: tuple index `2` exceeds length 2
+fail_compilation/ice12574.d(40): Error: tuple index `2` out of bounds `[0 .. 2]`
 fail_compilation/ice12574.d(53): Error: template instance `ice12574.reduce!("a", "a").reduce!(Tuple!(int, int, int))` error instantiating
 ---
 */
diff --git a/gcc/testsuite/gdc.test/fail_compilation/previewin.d b/gcc/testsuite/gdc.test/fail_compilation/previewin.d
index b3beaf4c9d8..ce0cf926a13 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/previewin.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/previewin.d
@@ -10,7 +10,7 @@  fail_compilation/previewin.d(6): Error: function `previewin.takeFunction(void fu
 fail_compilation/previewin.d(6):        cannot pass argument `__lambda3` of type `void function(ref const(real) x) pure nothrow @nogc @safe` to parameter `void function(in real) f`
 fail_compilation/previewin.d(15): Error: scope variable `arg` assigned to non-scope `myGlobal`
 fail_compilation/previewin.d(16): Error: scope variable `arg` assigned to non-scope `myGlobal`
-fail_compilation/previewin.d(17): Error: scope variable `arg` may not be returned
+fail_compilation/previewin.d(17): Error: scope parameter `arg` may not be returned
 fail_compilation/previewin.d(18): Error: scope variable `arg` assigned to `escape` with longer lifetime
 fail_compilation/previewin.d(22): Error: returning `arg` escapes a reference to parameter `arg`
 fail_compilation/previewin.d(22):        perhaps annotate the parameter with `return`
diff --git a/gcc/testsuite/gdc.test/fail_compilation/previewin2.d b/gcc/testsuite/gdc.test/fail_compilation/previewin2.d
new file mode 100644
index 00000000000..e9fe6a1fa88
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/previewin2.d
@@ -0,0 +1,18 @@ 
+/*
+REQUIRED_ARGS: -preview=in -preview=dip1000
+TEST_OUTPUT:
+---
+fail_compilation/previewin2.d(1): Error: cannot use `in` parameters with `extern(C)` functions
+fail_compilation/previewin2.d(1):        parameter `a` declared as `in` here
+fail_compilation/previewin2.d(2): Error: cannot use `in` parameters with `extern(Windows)` functions
+fail_compilation/previewin2.d(2):        parameter `a` declared as `in` here
+fail_compilation/previewin2.d(4): Error: cannot use `in` parameters with `extern(C)` functions
+fail_compilation/previewin2.d(4):        parameter `__anonymous_param` declared as `in` here
+---
+*/
+
+#line 1
+extern(C) void wrongLink1 (in int a);
+extern(Windows) void wrongLink2 (in void* a);
+struct Large { ulong[64] data; }
+extern(C) void wrongLink3 (in Large);
diff --git a/gcc/testsuite/gdc.test/fail_compilation/retscope.d b/gcc/testsuite/gdc.test/fail_compilation/retscope.d
index 27d566362bd..93944040db9 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/retscope.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/retscope.d
@@ -2,7 +2,7 @@ 
 REQUIRED_ARGS: -preview=dip1000
 TEST_OUTPUT:
 ---
-fail_compilation/retscope.d(22): Error: scope variable `p` may not be returned
+fail_compilation/retscope.d(22): Error: scope parameter `p` may not be returned
 fail_compilation/retscope.d(32): Error: returning `b ? nested1(& i) : nested2(& j)` escapes a reference to local variable `j`
 fail_compilation/retscope.d(45): Error: scope variable `p` assigned to non-scope `q`
 fail_compilation/retscope.d(47): Error: address of variable `i` assigned to `q` with longer lifetime
@@ -85,7 +85,7 @@  struct HTTP
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/retscope.d(96): Error: reference to local variable `sa` assigned to non-scope parameter `a`
+fail_compilation/retscope.d(96): Error: reference to local variable `sa` assigned to non-scope parameter `a` calling `bar8`
 ---
 */
 // https://issues.dlang.org/show_bug.cgi?id=8838
@@ -149,7 +149,7 @@  S10* test10()
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/retscope.d(158): Error: scope variable `this` may not be returned
+fail_compilation/retscope.d(158): Error: scope parameter `this` may not be returned
 ---
 */
 
@@ -218,7 +218,7 @@  void* escape3 (scope void* p) @safe {
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/retscope.d(229): Error: scope variable `ptr` may not be returned
+fail_compilation/retscope.d(229): Error: scope parameter `ptr` may not be returned
 ---
 */
 
@@ -403,7 +403,7 @@  class Foo13
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/retscope.d(1205): Error: scope variable `f14` assigned to non-scope parameter `this`
+fail_compilation/retscope.d(1205): Error: scope variable `f14` assigned to non-scope parameter `this` calling `foo`
 ---
 */
 
@@ -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`
+fail_compilation/retscope.d(1405): Error: reference to local variable `buf` assigned to non-scope parameter `__anonymous_param` calling `myprintf`
 ---
 */
 
diff --git a/gcc/testsuite/gdc.test/fail_compilation/retscope2.d b/gcc/testsuite/gdc.test/fail_compilation/retscope2.d
index 17d2182b454..9f1e13dde98 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`
-fail_compilation/retscope2.d(604): Error: scope variable `_param_1` assigned to non-scope parameter `__anonymous_param`
+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(614): Error: template instance `retscope2.test600!(int*, int*)` error instantiating
 ---
 */
diff --git a/gcc/testsuite/gdc.test/fail_compilation/retscope6.d b/gcc/testsuite/gdc.test/fail_compilation/retscope6.d
index b9a85aeddc1..a8e5de5dc6d 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/retscope6.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/retscope6.d
@@ -76,9 +76,9 @@  void foo() @safe
 /* TEST_OUTPUT:
 ---
 fail_compilation/retscope6.d(8016): Error: address of variable `i` assigned to `p` with longer lifetime
-fail_compilation/retscope6.d(8031): Error: reference to local variable `i` assigned to non-scope parameter `p`
-fail_compilation/retscope6.d(8031): Error: reference to local variable `j` assigned to non-scope parameter `q`
-fail_compilation/retscope6.d(8048): Error: reference to local variable `j` assigned to non-scope parameter `q`
+fail_compilation/retscope6.d(8031): Error: reference to local variable `i` assigned to non-scope parameter `p` calling `betty`
+fail_compilation/retscope6.d(8031): Error: reference to local variable `j` assigned to non-scope parameter `q` calling `betty`
+fail_compilation/retscope6.d(8048): Error: reference to local variable `j` assigned to non-scope parameter `q` calling `archie`
 ---
 */
 
@@ -172,7 +172,7 @@  T9 testfred()
 
 /* TEST_OUTPUT:
 ---
-fail_compilation/retscope6.d(10003): Error: scope variable `values` assigned to non-scope parameter `values`
+fail_compilation/retscope6.d(10003): Error: scope variable `values` assigned to non-scope parameter `values` calling `escape`
 ---
 */
 
@@ -234,7 +234,7 @@  const(int)* f_c_20150() @safe nothrow
 
 /* TEST_OUTPUT:
 ---
-fail_compilation/retscope6.d(13010): Error: reference to local variable `str` assigned to non-scope parameter `x`
+fail_compilation/retscope6.d(13010): Error: reference to local variable `str` assigned to non-scope parameter `x` calling `f_throw`
 ---
 */
 
@@ -254,7 +254,7 @@  void escape_throw_20150() @safe
 
 /* TEST_OUTPUT:
 ---
-fail_compilation/retscope6.d(14019): Error: scope variable `scopePtr` assigned to non-scope parameter `x`
+fail_compilation/retscope6.d(14019): Error: scope variable `scopePtr` assigned to non-scope parameter `x` calling `noInfer23021`
 fail_compilation/retscope6.d(14022): Error: scope variable `scopePtr` may not be returned
 ---
 */
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test14238.d b/gcc/testsuite/gdc.test/fail_compilation/test14238.d
index e0d0b35c4d6..a0e4d69b361 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/test14238.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/test14238.d
@@ -1,7 +1,7 @@ 
 /* REQUIRED_ARGS: -preview=dip1000
    TEST_OUTPUT:
 ---
-fail_compilation/test14238.d(20): Error: scope variable `fn` may not be returned
+fail_compilation/test14238.d(20): Error: scope parameter `fn` may not be returned
 fail_compilation/test14238.d(28): Error: escaping reference to stack allocated value returned by `&baz`
 ---
 */
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test17423.d b/gcc/testsuite/gdc.test/fail_compilation/test17423.d
index ec86646fc5a..3afb63b591b 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/test17423.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/test17423.d
@@ -1,7 +1,7 @@ 
 /* REQUIRED_ARGS: -preview=dip1000
 TEST_OUTPUT:
 ---
-fail_compilation/test17423.d(26): Error: reference to local `this` assigned to non-scope parameter `dlg`
+fail_compilation/test17423.d(26): Error: reference to local `this` assigned to non-scope parameter `dlg` calling `opApply`
 ---
 */
 
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test17450.d b/gcc/testsuite/gdc.test/fail_compilation/test17450.d
index 098adaae648..ddf3f46fb12 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/test17450.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/test17450.d
@@ -33,8 +33,8 @@  struct S {
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/test17450.d(103): Error: scope variable `c` may not be returned
-fail_compilation/test17450.d(106): Error: scope variable `this` may not be returned
+fail_compilation/test17450.d(103): Error: scope parameter `c` may not be returned
+fail_compilation/test17450.d(106): Error: scope parameter `this` may not be returned
 ---
 */
 // https://issues.dlang.org/show_bug.cgi?id=17450
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test20245.d b/gcc/testsuite/gdc.test/fail_compilation/test20245.d
index daa0697cffd..1713c9d8c27 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/test20245.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/test20245.d
@@ -2,15 +2,15 @@ 
 REQUIRED_ARGS: -preview=dip1000
 TEST_OUTPUT:
 ---
-fail_compilation/test20245.d(20): Error: reference to local variable `x` assigned to non-scope parameter `ptr`
+fail_compilation/test20245.d(20): Error: reference to local variable `x` assigned to non-scope parameter `ptr` calling `escape`
 fail_compilation/test20245.d(21): Error: copying `&x` into allocated memory escapes a reference to parameter `x`
 fail_compilation/test20245.d(22): Error: scope variable `a` may not be returned
 fail_compilation/test20245.d(26): Error: cannot take address of `scope` variable `x` since `scope` applies to first indirection only
-fail_compilation/test20245.d(32): Error: reference to local variable `x` assigned to non-scope parameter `ptr`
+fail_compilation/test20245.d(32): Error: reference to local variable `x` assigned to non-scope parameter `ptr` calling `escape`
 fail_compilation/test20245.d(33): Error: copying `&x` into allocated memory escapes a reference to parameter `x`
 fail_compilation/test20245.d(49): Error: reference to local variable `price` assigned to non-scope `this.minPrice`
-fail_compilation/test20245.d(68): Error: reference to local variable `this` assigned to non-scope parameter `msg`
-fail_compilation/test20245.d(88): Error: reference to local variable `this` assigned to non-scope parameter `content`
+fail_compilation/test20245.d(68): Error: reference to local variable `this` assigned to non-scope parameter `msg` calling `this`
+fail_compilation/test20245.d(88): Error: reference to local variable `this` assigned to non-scope parameter `content` calling `listUp`
 ---
 */
 
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test22818.d b/gcc/testsuite/gdc.test/fail_compilation/test22818.d
index ae96b3bc109..5759415ead2 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/test22818.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/test22818.d
@@ -1,7 +1,7 @@ 
 /* REQUIRED_ARGS: -preview=dip1000
  * TEST_OUTPUT:
 ---
-fail_compilation/test22818.d(104): Error: scope variable `c` may not be returned
+fail_compilation/test22818.d(104): Error: scope parameter `c` may not be returned
 ---
 */
 
diff --git a/gcc/testsuite/gdc.test/fail_compilation/typeerrors.d b/gcc/testsuite/gdc.test/fail_compilation/typeerrors.d
index 37395d4b897..9d527b75d71 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/typeerrors.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/typeerrors.d
@@ -2,7 +2,7 @@ 
 TEST_OUTPUT:
 ---
 fail_compilation/typeerrors.d(32): Deprecation: `scope` as a type constraint is deprecated.  Use `scope` at the usage site.
-fail_compilation/typeerrors.d(37): Error: tuple index 4 exceeds 4
+fail_compilation/typeerrors.d(37): Error: tuple index `4` out of bounds `[0 .. 4]`
 fail_compilation/typeerrors.d(39): Error: variable `x` cannot be read at compile time
 fail_compilation/typeerrors.d(40): Error: cannot have array of `void()`
 fail_compilation/typeerrors.d(41): Error: cannot have array of scope `typeerrors.C`
diff --git a/gcc/testsuite/gdc.test/fail_compilation/udaparams.d b/gcc/testsuite/gdc.test/fail_compilation/udaparams.d
index 5d0390f4f29..ec4796789ac 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/udaparams.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/udaparams.d
@@ -12,8 +12,8 @@  fail_compilation/udaparams.d(40): Error: `@safe` attribute for function paramete
 fail_compilation/udaparams.d(43): Error: `@system` attribute for function parameter is not supported
 fail_compilation/udaparams.d(44): Error: `@trusted` attribute for function parameter is not supported
 fail_compilation/udaparams.d(45): Error: `@nogc` attribute for function parameter is not supported
-fail_compilation/udaparams.d(51): Error: cannot put a storage-class in an alias declaration.
-fail_compilation/udaparams.d(52): Error: cannot put a storage-class in an alias declaration.
+fail_compilation/udaparams.d(51): Error: cannot put a storage-class in an `alias` declaration.
+fail_compilation/udaparams.d(52): Error: cannot put a storage-class in an `alias` declaration.
 fail_compilation/udaparams.d(53): Error: semicolon expected to close `alias` declaration
 fail_compilation/udaparams.d(53): Error: declaration expected, not `=>`
 fail_compilation/udaparams.d(54): Error: semicolon expected to close `alias` declaration
diff --git a/gcc/testsuite/gdc.test/fail_compilation/udatypes.d b/gcc/testsuite/gdc.test/fail_compilation/udatypes.d
new file mode 100644
index 00000000000..a7f2bfc521f
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/udatypes.d
@@ -0,0 +1,8 @@ 
+/*
+TEST_OUTPUT:
+---
+fail_compilation/udatypes.d(8): Error: user-defined attributes not allowed for `alias` declarations
+---
+*/
+
+alias c_typedef = extern(C) @(1) void* function(size_t);
diff --git a/gcc/testsuite/gdc.test/runnable/ice10086b.d b/gcc/testsuite/gdc.test/runnable/ice10086b.d
index abb6f78a4ac..910c5c4a7a2 100644
--- a/gcc/testsuite/gdc.test/runnable/ice10086b.d
+++ b/gcc/testsuite/gdc.test/runnable/ice10086b.d
@@ -5,3 +5,53 @@  import imports.ice10086y;
 import imports.ice10086x;
 
 void main() { test(); }
+
+static if (0)
+{
+/* this is a reduced one-file version that triggers a seg fault
+because the use of OPframeptr gets inlined, and the offests
+to it are not updated.
+Compile with: -O -inline
+*/
+
+pragma(inline, false)
+auto bind(alias f, bindValues...)()
+{
+    pragma(inline, false)
+    auto bind(Types...)(Types values)
+    {
+        return f(bindValues, values);
+    }
+    return bind();
+}
+
+
+struct SS
+{
+    int a1 = 123;
+}
+
+pragma(inline, false)
+@safe auto ff(SS rr)
+{
+    return rr;
+}
+
+//   pragma(inline, false)
+@safe auto gg(SS ss)  // this getting inlined triggers the problem
+{
+    return bind!(ff, ss);
+}
+
+pragma(inline, false)
+void test()
+{
+    SS s1;
+
+    auto zb = bind!(gg, s1)();
+    assert(zb.a1 == 123);
+}
+
+
+void main() { test(); }
+}
diff --git a/gcc/testsuite/gdc.test/runnable/inline3.d b/gcc/testsuite/gdc.test/runnable/inline3.d
new file mode 100644
index 00000000000..01af5c8cbe5
--- /dev/null
+++ b/gcc/testsuite/gdc.test/runnable/inline3.d
@@ -0,0 +1,44 @@ 
+// REQUIRED_ARGS: -inline -O
+
+// Test operator overloading
+
+extern (C) int printf(const(char*) fmt, ...);
+
+struct Tuple6798(T...)
+{
+    T field;
+    alias field this;
+
+    bool opEquals(Tuple6798 rxx)
+    {
+        foreach (i, _; T)
+        {
+            if (!__equals(this[i], rxx[i]))
+                assert(0);
+                //return false;
+        }
+        return true;
+    }
+}
+
+auto tuple(T...)(T args)
+{
+    return Tuple6798!T(args);
+}
+
+int zzzz()
+{
+    if (!__equals("mno", "mno"))
+        assert(0);
+
+    assert(tuple("abcd", "x") == tuple("abcd", "x"));
+    return 0;
+}
+
+int main()
+{
+    zzzz();
+
+    printf("Success\n");
+    return 0;
+}
diff --git a/gcc/testsuite/gdc.test/runnable/staticforeach.d b/gcc/testsuite/gdc.test/runnable/staticforeach.d
index bf6dc983935..6a9ac5deb2f 100644
--- a/gcc/testsuite/gdc.test/runnable/staticforeach.d
+++ b/gcc/testsuite/gdc.test/runnable/staticforeach.d
@@ -39,7 +39,36 @@  void test19479()
     }
 }
 
+/**********************************/
+// https://issues.dlang.org/show_bug.cgi?id=23192
+
+alias AliasSeq(Args...) = Args;
+
+struct S23192
+{
+    int x;
+    int y;
+
+    int fun()
+    {
+        static foreach (sym; AliasSeq!(S23192.x))
+            int i = sym;
+
+        static foreach (sym; AliasSeq!(this.y))
+            int j = sym;
+
+        return i + j;
+    }
+}
+
+void test23192()
+{
+    assert(S23192(1, 2).fun() == 3);
+    static assert(S23192(1, 2).fun() == 3);
+}
+
 void main()
 {
     test19479();
+    test23192();
 }
diff --git a/gcc/testsuite/gdc.test/runnable_cxx/cppa.d b/gcc/testsuite/gdc.test/runnable_cxx/cppa.d
index e31588948a6..cd91dd55834 100644
--- a/gcc/testsuite/gdc.test/runnable_cxx/cppa.d
+++ b/gcc/testsuite/gdc.test/runnable_cxx/cppa.d
@@ -1,3 +1,4 @@ 
+// REQUIRED_ARGS: -preview=in
 // PERMUTE_ARGS: -g
 // EXTRA_CPP_SOURCES: cppb.cpp
 // EXTRA_FILES: extra-files/cppb.h
@@ -1637,7 +1638,13 @@  void test19134()
 }
 
 // https://issues.dlang.org/show_bug.cgi?id=18955
-alias std_string = std.basic_string!(char);
+version (linux)
+    alias std_string = std.basic_string!(char);
+else
+{
+    import core.stdcpp.string : core_basic_string = basic_string;
+    alias std_string = core_basic_string!(char);
+}
 
 extern(C++) void callback18955(ref const(std_string) str)
 {
@@ -1646,6 +1653,16 @@  extern(C++) void test18955();
 
 /****************************************/
 
+extern(C++) void testPreviewIn();
+
+extern(C++) void previewInFunction(in int a, in std_string b, ref const(std_string) c)
+{
+    assert(a == 42);
+    assert(&b is &c);
+}
+
+/****************************************/
+
 void main()
 {
     test1();
@@ -1695,6 +1712,7 @@  void main()
     test18966();
     test19134();
     test18955();
+    testPreviewIn();
 
     printf("Success\n");
 }
diff --git a/gcc/testsuite/gdc.test/runnable_cxx/extra-files/cppb.cpp b/gcc/testsuite/gdc.test/runnable_cxx/extra-files/cppb.cpp
index 4fa87efcfff..83667cbddc7 100644
--- a/gcc/testsuite/gdc.test/runnable_cxx/extra-files/cppb.cpp
+++ b/gcc/testsuite/gdc.test/runnable_cxx/extra-files/cppb.cpp
@@ -4,30 +4,8 @@ 
 #include <exception>
 #include <cstdarg>
 
-#if _WIN32 // otherwise defined in C header files!
-// https://issues.dlang.org/show_bug.cgi?id=18955
-namespace std
-{
-    template<typename Char>
-    struct char_traits
-    {
-    };
-    template<typename Char>
-    class allocator
-    {
-    };
-    template<typename Char, typename Traits, typename Alloc>
-    class basic_string
-    {
-    };
-    typedef basic_string<char, char_traits<char>, allocator<char> > string;
-}
-#else // if POSIX
-
 #include <string>
 
-#endif // _WIN32
-
 #include "cppb.h"
 
 /**************************************/
@@ -936,3 +914,11 @@  void test18955()
     callback18955(s);
 #endif
 }
+
+void previewInFunction(const int& a, const std::string& b, const std::string& c);
+
+void testPreviewIn()
+{
+    std::string s = "Hello World";
+    previewInFunction(42, s, s);
+}
diff --git a/libphobos/libdruntime/MERGE b/libphobos/libdruntime/MERGE
index 8b2839da46c..3f4a0ec63e3 100644
--- a/libphobos/libdruntime/MERGE
+++ b/libphobos/libdruntime/MERGE
@@ -1,4 +1,4 @@ 
-454471d8077d12ec6bf0ae8fcd9571aad1bce7be
+e150cca179515ce5113e828aac94c20c0b983b7c
 
 The first line of this file holds the git revision number of the last
 merge done from the dlang/druntime repository.
diff --git a/libphobos/libdruntime/core/stdc/config.d b/libphobos/libdruntime/core/stdc/config.d
index 037af25a675..c576e991db5 100644
--- a/libphobos/libdruntime/core/stdc/config.d
+++ b/libphobos/libdruntime/core/stdc/config.d
@@ -185,6 +185,37 @@  else version (Posix)
     alias ulong cpp_ulonglong;
   }
 }
+else version (WASI)
+{
+    static if ( (void*).sizeof > int.sizeof )
+    {
+        enum __c_longlong  : long;
+        enum __c_ulonglong : ulong;
+
+        alias long  c_long;
+        alias ulong c_ulong;
+
+        alias long   cpp_long;
+        alias ulong  cpp_ulong;
+
+        alias __c_longlong  cpp_longlong;
+        alias __c_ulonglong cpp_ulonglong;
+    }
+    else
+    {
+        enum __c_long  : int;
+        enum __c_ulong : uint;
+
+        alias int   c_long;
+        alias uint  c_ulong;
+
+        alias __c_long   cpp_long;
+        alias __c_ulong  cpp_ulong;
+
+        alias long  cpp_longlong;
+        alias ulong cpp_ulonglong;
+    }
+}
 
 version (GNU)
     alias c_long_double = real;
diff --git a/libphobos/libdruntime/core/stdc/errno.d b/libphobos/libdruntime/core/stdc/errno.d
index 57bc15da6eb..24b4138153d 100644
--- a/libphobos/libdruntime/core/stdc/errno.d
+++ b/libphobos/libdruntime/core/stdc/errno.d
@@ -2079,6 +2079,143 @@  else version (Haiku)
     enum B_NO_TRANSLATOR                 = (B_TRANSLATION_ERROR_BASE + 1);
     enum B_ILLEGAL_DATA                  = (B_TRANSLATION_ERROR_BASE + 2);
 }
+else version (WASI)
+{
+    enum EPERM            = 1;
+    enum ENOENT           = 2;
+    enum ESRCH            = 3;
+    enum EINTR            = 4;
+    enum EIO              = 5;
+    enum ENXIO            = 6;
+    enum E2BIG            = 7;
+    enum ENOEXEC          = 8;
+    enum EBADF            = 9;
+    enum ECHILD          = 10;
+    enum EAGAIN          = 11;
+    enum ENOMEM          = 12;
+    enum EACCES          = 13;
+    enum EFAULT          = 14;
+    enum ENOTBLK         = 15;
+    enum EBUSY           = 16;
+    enum EEXIST          = 17;
+    enum EXDEV           = 18;
+    enum ENODEV          = 19;
+    enum ENOTDIR         = 20;
+    enum EISDIR          = 21;
+    enum EINVAL          = 22;
+    enum ENFILE          = 23;
+    enum EMFILE          = 24;
+    enum ENOTTY          = 25;
+    enum ETXTBSY         = 26;
+    enum EFBIG           = 27;
+    enum ENOSPC          = 28;
+    enum ESPIPE          = 29;
+    enum EROFS           = 30;
+    enum EMLINK          = 31;
+    enum EPIPE           = 32;
+    enum EDOM            = 33;
+    enum ERANGE          = 34;
+    enum EDEADLK         = 35;
+    enum ENAMETOOLONG    = 36;
+    enum ENOLCK          = 37;
+    enum ENOSYS          = 38;
+    enum ENOTEMPTY       = 39;
+    enum ELOOP           = 40;
+    enum EWOULDBLOCK     = EAGAIN;
+    enum ENOMSG          = 42;
+    enum EIDRM           = 43;
+    enum ECHRNG          = 44;
+    enum EL2NSYNC        = 45;
+    enum EL3HLT          = 46;
+    enum EL3RST          = 47;
+    enum ELNRNG          = 48;
+    enum EUNATCH         = 49;
+    enum ENOCSI          = 50;
+    enum EL2HLT          = 51;
+    enum EBADE           = 52;
+    enum EBADR           = 53;
+    enum EXFULL          = 54;
+    enum ENOANO          = 55;
+    enum EBADRQC         = 56;
+    enum EBADSLT         = 57;
+    enum EDEADLOCK       = EDEADLK;
+    enum EBFONT          = 59;
+    enum ENOSTR          = 60;
+    enum ENODATA         = 61;
+    enum ETIME           = 62;
+    enum ENOSR           = 63;
+    enum ENONET          = 64;
+    enum ENOPKG          = 65;
+    enum EREMOTE         = 66;
+    enum ENOLINK         = 67;
+    enum EADV            = 68;
+    enum ESRMNT          = 69;
+    enum ECOMM           = 70;
+    enum EPROTO          = 71;
+    enum EMULTIHOP       = 72;
+    enum EDOTDOT         = 73;
+    enum EBADMSG         = 74;
+    enum EOVERFLOW       = 75;
+    enum ENOTUNIQ        = 76;
+    enum EBADFD          = 77;
+    enum EREMCHG         = 78;
+    enum ELIBACC         = 79;
+    enum ELIBBAD         = 80;
+    enum ELIBSCN         = 81;
+    enum ELIBMAX         = 82;
+    enum ELIBEXEC        = 83;
+    enum EILSEQ          = 84;
+    enum ERESTART        = 85;
+    enum ESTRPIPE        = 86;
+    enum EUSERS          = 87;
+    enum ENOTSOCK        = 88;
+    enum EDESTADDRREQ    = 89;
+    enum EMSGSIZE        = 90;
+    enum EPROTOTYPE      = 91;
+    enum ENOPROTOOPT     = 92;
+    enum EPROTONOSUPPORT = 93;
+    enum ESOCKTNOSUPPORT = 94;
+    enum EOPNOTSUPP      = 95;
+    enum ENOTSUP         = EOPNOTSUPP;
+    enum EPFNOSUPPORT    = 96;
+    enum EAFNOSUPPORT    = 97;
+    enum EADDRINUSE      = 98;
+    enum EADDRNOTAVAIL   = 99;
+    enum ENETDOWN        = 100;
+    enum ENETUNREACH     = 101;
+    enum ENETRESET       = 102;
+    enum ECONNABORTED    = 103;
+    enum ECONNRESET      = 104;
+    enum ENOBUFS         = 105;
+    enum EISCONN         = 106;
+    enum ENOTCONN        = 107;
+    enum ESHUTDOWN       = 108;
+    enum ETOOMANYREFS    = 109;
+    enum ETIMEDOUT       = 110;
+    enum ECONNREFUSED    = 111;
+    enum EHOSTDOWN       = 112;
+    enum EHOSTUNREACH    = 113;
+    enum EALREADY        = 114;
+    enum EINPROGRESS     = 115;
+    enum ESTALE          = 116;
+    enum EUCLEAN         = 117;
+    enum ENOTNAM         = 118;
+    enum ENAVAIL         = 119;
+    enum EISNAM          = 120;
+    enum EREMOTEIO       = 121;
+    enum EDQUOT          = 122;
+    enum ENOMEDIUM       = 123;
+    enum EMEDIUMTYPE     = 124;
+    enum ECANCELED       = 125;
+    enum ENOKEY          = 126;
+    enum EKEYEXPIRED     = 127;
+    enum EKEYREVOKED     = 128;
+    enum EKEYREJECTED    = 129;
+    enum EOWNERDEAD      = 130;
+    enum ENOTRECOVERABLE = 131;
+    enum ERFKILL         = 132;
+    enum EHWPOISON       = 133;
+}
 else
 {
     static assert(false, "Unsupported platform");
diff --git a/libphobos/libdruntime/core/stdc/stdarg.d b/libphobos/libdruntime/core/stdc/stdarg.d
index 9a67f2e8e4d..646905eaffb 100644
--- a/libphobos/libdruntime/core/stdc/stdarg.d
+++ b/libphobos/libdruntime/core/stdc/stdarg.d
@@ -47,6 +47,8 @@  version (MIPS32)  version = MIPS_Any;
 version (MIPS64)  version = MIPS_Any;
 version (PPC)     version = PPC_Any;
 version (PPC64)   version = PPC_Any;
+version (RISCV32) version = RISCV_Any;
+version (RISCV64) version = RISCV_Any;
 
 version (GNU)
 {
@@ -130,6 +132,12 @@  else version (AAPCS64)
 {
     alias va_list = core.internal.vararg.aarch64.va_list;
 }
+else version (RISCV_Any)
+{
+    // The va_list type is void*, according to RISCV Calling Convention
+    // https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-cc.adoc
+    alias va_list = void*;
+}
 else
 {
     alias va_list = char*; // incl. unknown platforms
@@ -259,6 +267,19 @@  T va_arg(T)(ref va_list ap)
         ap += T.sizeof.alignUp;
         return *p;
     }
+    else version (RISCV_Any)
+    {
+        static if (T.sizeof > (size_t.sizeof << 1))
+            auto p = *cast(T**) ap;
+        else
+        {
+            static if (T.alignof == (size_t.sizeof << 1))
+                ap = ap.alignUp!(size_t.sizeof << 1);
+            auto p = cast(T*) ap;
+        }
+        ap += T.sizeof.alignUp;
+        return *p;
+    }
     else
         static assert(0, "Unsupported platform");
 }
diff --git a/libphobos/libdruntime/core/stdc/stddef.d b/libphobos/libdruntime/core/stdc/stddef.d
index 1d1d96255b9..56b3c9b3f90 100644
--- a/libphobos/libdruntime/core/stdc/stddef.d
+++ b/libphobos/libdruntime/core/stdc/stddef.d
@@ -34,3 +34,8 @@  else version (Posix)
     ///
     alias dchar wchar_t;
 }
+else version (WASI)
+{
+    ///
+    alias dchar wchar_t;
+}
diff --git a/libphobos/libdruntime/core/stdc/stdint.d b/libphobos/libdruntime/core/stdc/stdint.d
index 556ac019eeb..476c42f08ee 100644
--- a/libphobos/libdruntime/core/stdc/stdint.d
+++ b/libphobos/libdruntime/core/stdc/stdint.d
@@ -377,6 +377,41 @@  else version (Solaris)
     alias intmax_t  = long;      ///
     alias uintmax_t = ulong;     ///
 }
+else version (WASI)
+{
+    alias int8_t   = byte;   ///
+    alias int16_t  = short;  ///
+    alias uint8_t  = ubyte;  ///
+    alias uint16_t = ushort; ///
+    alias int32_t  = int;    ///
+    alias uint32_t = uint;   ///
+    alias int64_t  = long;   ///
+    alias uint64_t = ulong;  ///
+
+    alias int_least8_t   = byte;   ///
+    alias uint_least8_t  = ubyte;  ///
+    alias int_least16_t  = short;  ///
+    alias uint_least16_t = ushort; ///
+    alias int_least32_t  = int;    ///
+    alias uint_least32_t = uint;   ///
+    alias int_least64_t  = long;   ///
+    alias uint_least64_t = ulong;  ///
+
+    alias int_fast8_t   = byte;      ///
+    alias uint_fast8_t  = ubyte;     ///
+    alias int_fast16_t  = ptrdiff_t; ///
+    alias uint_fast16_t = size_t;    ///
+    alias int_fast32_t  = ptrdiff_t; ///
+    alias uint_fast32_t = size_t;    ///
+
+    alias int_fast64_t  = long;      ///
+    alias uint_fast64_t = ulong;     ///
+
+    alias intptr_t  = ptrdiff_t; ///
+    alias uintptr_t = size_t;    ///
+    alias intmax_t  = long;      ///
+    alias uintmax_t = ulong;     ///
+}
 else
 {
     static assert(false, "Unsupported architecture.");
diff --git a/libphobos/libdruntime/core/stdc/stdio.d b/libphobos/libdruntime/core/stdc/stdio.d
index cd53f0ab50b..2e8381180db 100644
--- a/libphobos/libdruntime/core/stdc/stdio.d
+++ b/libphobos/libdruntime/core/stdc/stdio.d
@@ -347,6 +347,24 @@  else version (CRuntime_UClibc)
         L_tmpnam     = 20
     }
 }
+else version (WASI)
+{
+    enum
+    {
+        ///
+        BUFSIZ       = 1024,
+        ///
+        EOF          = -1,
+        ///
+        FOPEN_MAX    = 1000,
+        ///
+        FILENAME_MAX = 4096,
+        ///
+        TMP_MAX      = 10000,
+        ///
+        L_tmpnam     = 20
+    }
+}
 else
 {
     static assert( false, "Unsupported platform" );
@@ -449,6 +467,20 @@  else version (CRuntime_Glibc)
     ///
     alias shared(_IO_FILE) FILE;
 }
+else version (WASI)
+{
+    union fpos_t
+    {
+        char[16] __opaque = 0;
+        double __align;
+    }
+    struct _IO_FILE;
+
+    ///
+    alias _IO_FILE _iobuf; // needed for phobos
+    ///
+    alias shared(_IO_FILE) FILE;
+}
 else version (CRuntime_Musl)
 {
     union fpos_t
@@ -1125,6 +1157,24 @@  else version (CRuntime_UClibc)
     ///
     extern shared FILE* stderr;
 }
+else version (WASI)
+{
+    // needs tail const
+    extern shared FILE* stdin;
+    ///
+    extern shared FILE* stdout;
+    ///
+    extern shared FILE* stderr;
+    enum
+    {
+        ///
+        _IOFBF = 0,
+        ///
+        _IOLBF = 1,
+        ///
+        _IONBF = 2,
+    }
+}
 else
 {
     static assert( false, "Unsupported platform" );
@@ -1793,6 +1843,28 @@  else version (CRuntime_UClibc)
     pragma(printf)
     int  vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg);
 }
+else version (WASI)
+{
+    // No unsafe pointer manipulation.
+    @trusted
+    {
+        ///
+        void rewind(FILE* stream);
+        ///
+        pure void clearerr(FILE* stream);
+        ///
+        pure int  feof(FILE* stream);
+        ///
+        pure int  ferror(FILE* stream);
+        ///
+        int  fileno(FILE *);
+    }
+
+    ///
+    int  snprintf(scope char* s, size_t n, scope const char* format, ...);
+    ///
+    int  vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg);
+}
 else
 {
     static assert( false, "Unsupported platform" );
diff --git a/libphobos/libdruntime/core/stdc/stdlib.d b/libphobos/libdruntime/core/stdc/stdlib.d
index dbe55a4b340..920c3117732 100644
--- a/libphobos/libdruntime/core/stdc/stdlib.d
+++ b/libphobos/libdruntime/core/stdc/stdlib.d
@@ -99,6 +99,7 @@  else version (Solaris) enum RAND_MAX = 0x7fff;
 else version (CRuntime_Bionic) enum RAND_MAX = 0x7fffffff;
 else version (CRuntime_Musl) enum RAND_MAX = 0x7fffffff;
 else version (CRuntime_UClibc) enum RAND_MAX = 0x7fffffff;
+else version (WASI) enum RAND_MAX = 0x7fffffff;
 else static assert( false, "Unsupported platform" );
 
 ///
diff --git a/libphobos/libdruntime/core/sys/elf/package.d b/libphobos/libdruntime/core/sys/elf/package.d
index 69e52093dc3..2dcfd201dd5 100644
--- a/libphobos/libdruntime/core/sys/elf/package.d
+++ b/libphobos/libdruntime/core/sys/elf/package.d
@@ -2510,3 +2510,66 @@  enum R_TILEGX_GNU_VTINHERIT =  128;
 enum R_TILEGX_GNU_VTENTRY =    129;
 
 enum R_TILEGX_NUM =            130;
+
+enum EF_RISCV_RVC =              0x0001;
+enum EF_RISCV_FLOAT_ABI =        0x0006;
+enum EF_RISCV_FLOAT_ABI_SOFT =   0x0000;
+enum EF_RISCV_FLOAT_ABI_SINGLE = 0x0002;
+enum EF_RISCV_FLOAT_ABI_DOUBLE = 0x0004;
+enum EF_RISCV_FLOAT_ABI_QUAD =   0x0006;
+enum R_RISCV_NONE =            0;
+enum R_RISCV_32 =              1;
+enum R_RISCV_64 =              2;
+enum R_RISCV_RELATIVE =        3;
+enum R_RISCV_COPY =            4;
+enum R_RISCV_JUMP_SLOT =       5;
+enum R_RISCV_TLS_DTPMOD32 =    6;
+enum R_RISCV_TLS_DTPMOD64 =    7;
+enum R_RISCV_TLS_DTPREL32 =    8;
+enum R_RISCV_TLS_DTPREL64 =    9;
+enum R_RISCV_TLS_TPREL32 =     10;
+enum R_RISCV_TLS_TPREL64 =     11;
+enum R_RISCV_BRANCH =          16;
+enum R_RISCV_JAL =             17;
+enum R_RISCV_CALL =            18;
+enum R_RISCV_CALL_PLT =        19;
+enum R_RISCV_GOT_HI20 =        20;
+enum R_RISCV_TLS_GOT_HI20 =    21;
+enum R_RISCV_TLS_GD_HI20 =     22;
+enum R_RISCV_PCREL_HI20 =      23;
+enum R_RISCV_PCREL_LO12_I =    24;
+enum R_RISCV_PCREL_LO12_S =    25;
+enum R_RISCV_HI20 =            26;
+enum R_RISCV_LO12_I =          27;
+enum R_RISCV_LO12_S =          28;
+enum R_RISCV_TPREL_HI20 =      29;
+enum R_RISCV_TPREL_LO12_I =    30;
+enum R_RISCV_TPREL_LO12_S =    31;
+enum R_RISCV_TPREL_ADD =       32;
+enum R_RISCV_ADD8 =            33;
+enum R_RISCV_ADD16 =           34;
+enum R_RISCV_ADD32 =           35;
+enum R_RISCV_ADD64 =           36;
+enum R_RISCV_SUB8 =            37;
+enum R_RISCV_SUB16 =           38;
+enum R_RISCV_SUB32 =           39;
+enum R_RISCV_SUB64 =           40;
+enum R_RISCV_GNU_VTINHERIT =   41;
+enum R_RISCV_GNU_VTENTRY =     42;
+enum R_RISCV_ALIGN =           43;
+enum R_RISCV_RVC_BRANCH =      44;
+enum R_RISCV_RVC_JUMP =        45;
+enum R_RISCV_RVC_LUI =         46;
+enum R_RISCV_GPREL_I =         47;
+enum R_RISCV_GPREL_S =         48;
+enum R_RISCV_TPREL_I =         49;
+enum R_RISCV_TPREL_S =         50;
+enum R_RISCV_RELAX =           51;
+enum R_RISCV_SUB6 =            52;
+enum R_RISCV_SET6 =            53;
+enum R_RISCV_SET8 =            54;
+enum R_RISCV_SET16 =           55;
+enum R_RISCV_SET32 =           56;
+enum R_RISCV_32_PCREL =        57;
+enum R_RISCV_IRELATIVE =       58;
+enum R_RISCV_NUM =             59;
diff --git a/libphobos/libdruntime/core/sys/posix/fcntl.d b/libphobos/libdruntime/core/sys/posix/fcntl.d
index 3c196d29f22..dc0a183f25e 100644
--- a/libphobos/libdruntime/core/sys/posix/fcntl.d
+++ b/libphobos/libdruntime/core/sys/posix/fcntl.d
@@ -123,6 +123,12 @@  version (linux)
     enum F_SETLK        = 6;
     enum F_SETLKW       = 7;
   }
+  else version (RISCV64)
+  {
+    enum F_GETLK        = 5;
+    enum F_SETLK        = 6;
+    enum F_SETLKW       = 7;
+  }
   else version (SystemZ)
   {
     static assert(off_t.sizeof == 8);
diff --git a/libphobos/libdruntime/core/sys/windows/winsock2.d b/libphobos/libdruntime/core/sys/windows/winsock2.d
index 55a45be85bf..8a4b1fda274 100644
--- a/libphobos/libdruntime/core/sys/windows/winsock2.d
+++ b/libphobos/libdruntime/core/sys/windows/winsock2.d
@@ -45,15 +45,15 @@  enum NI_MAXSERV = 32;
 @nogc
 {
 int WSAStartup(ushort wVersionRequested, LPWSADATA lpWSAData);
-int WSACleanup();
-SOCKET socket(int af, int type, int protocol);
+@trusted int WSACleanup();
+@trusted SOCKET socket(int af, int type, int protocol);
 int ioctlsocket(SOCKET s, int cmd, uint* argp);
 int bind(SOCKET s, const(sockaddr)* name, socklen_t namelen);
 int connect(SOCKET s, const(sockaddr)* name, socklen_t namelen);
-int listen(SOCKET s, int backlog);
+@trusted int listen(SOCKET s, int backlog);
 SOCKET accept(SOCKET s, sockaddr* addr, socklen_t* addrlen);
-int closesocket(SOCKET s);
-int shutdown(SOCKET s, int how);
+@trusted int closesocket(SOCKET s);
+@trusted int shutdown(SOCKET s, int how);
 int getpeername(SOCKET s, sockaddr* name, socklen_t* namelen);
 int getsockname(SOCKET s, sockaddr* name, socklen_t* namelen);
 int send(SOCKET s, const(void)* buf, int len, int flags);
@@ -64,11 +64,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);
-char* inet_ntoa(in_addr ina);
+@trusted 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);
-protoent* getprotobynumber(int number);
+@trusted protoent* getprotobynumber(int number);
 servent* getservbyname(const char* name, const char* proto);
 servent* getservbyport(int port, const char* proto);
 }
diff --git a/libphobos/libdruntime/core/thread/osthread.d b/libphobos/libdruntime/core/thread/osthread.d
index ef073a93324..1165320f8f8 100644
--- a/libphobos/libdruntime/core/thread/osthread.d
+++ b/libphobos/libdruntime/core/thread/osthread.d
@@ -2104,7 +2104,7 @@  private extern (D) void resume(ThreadBase _t) nothrow @nogc
  * garbage collector on startup and before any other thread routines
  * are called.
  */
-extern (C) void thread_init() @nogc
+extern (C) void thread_init() @nogc nothrow
 {
     // NOTE: If thread_init itself performs any allocations then the thread
     //       routines reserved for garbage collector use may be called while
@@ -2191,7 +2191,7 @@  package __gshared align(__traits(classInstanceAlignment, Thread)) MainThreadStor
  * Terminates the thread module. No other thread routine may be called
  * afterwards.
  */
-extern (C) void thread_term() @nogc
+extern (C) void thread_term() @nogc nothrow
 {
     thread_term_tpl!(Thread)(_mainThreadStore);
 }
diff --git a/libphobos/libdruntime/core/thread/threadbase.d b/libphobos/libdruntime/core/thread/threadbase.d
index 217a33a0cf0..909bffc162b 100644
--- a/libphobos/libdruntime/core/thread/threadbase.d
+++ b/libphobos/libdruntime/core/thread/threadbase.d
@@ -569,14 +569,14 @@  package(core.thread):
     __gshared align(mutexAlign) void[mutexClassInstanceSize] _slock;
     __gshared align(mutexAlign) void[mutexClassInstanceSize] _criticalRegionLock;
 
-    static void initLocks() @nogc
+    static void initLocks() @nogc nothrow
     {
         import core.lifetime : emplace;
         emplace!Mutex(_slock[]);
         emplace!Mutex(_criticalRegionLock[]);
     }
 
-    static void termLocks() @nogc
+    static void termLocks() @nogc nothrow
     {
         (cast(Mutex)_slock.ptr).__dtor();
         (cast(Mutex)_criticalRegionLock.ptr).__dtor();
@@ -756,13 +756,13 @@  package(core.thread):
 
 private alias attachThread = externDFunc!("core.thread.osthread.attachThread", ThreadBase function(ThreadBase) @nogc nothrow);
 
-extern (C) void _d_monitordelete_nogc(Object h) @nogc;
+extern (C) void _d_monitordelete_nogc(Object h) @nogc nothrow;
 
 /**
  * Terminates the thread module. No other thread routine may be called
  * afterwards.
  */
-package void thread_term_tpl(ThreadT, MainThreadStore)(ref MainThreadStore _mainThreadStore) @nogc
+package void thread_term_tpl(ThreadT, MainThreadStore)(ref MainThreadStore _mainThreadStore) @nogc nothrow
 {
     assert(_mainThreadStore.ptr is cast(void*) ThreadBase.sm_main);
 
@@ -1332,13 +1332,13 @@  package
         return cast(Mutex)ll_lock.ptr;
     }
 
-    void initLowlevelThreads() @nogc
+    void initLowlevelThreads() @nogc nothrow
     {
         import core.lifetime : emplace;
         emplace(lowlevelLock());
     }
 
-    void termLowlevelThreads() @nogc
+    void termLowlevelThreads() @nogc nothrow
     {
         lowlevelLock.__dtor();
     }
diff --git a/libphobos/libdruntime/core/time.d b/libphobos/libdruntime/core/time.d
index 91f218e27fb..9b8391e7207 100644
--- a/libphobos/libdruntime/core/time.d
+++ b/libphobos/libdruntime/core/time.d
@@ -2488,7 +2488,7 @@  private immutable long[__traits(allMembers, ClockType).length] _ticksPerSecond;
 // https://issues.dlang.org/show_bug.cgi?id=14863
 // The assert will occur when someone attempts to use _ticksPerSecond for that
 // value.
-extern(C) void _d_initMonoTime()
+extern(C) void _d_initMonoTime() @nogc nothrow
 {
     // We need a mutable pointer to the ticksPerSecond array. Although this
     // would appear to break immutability, it is logically the same as a static
@@ -3823,7 +3823,7 @@  unittest
 }
 
 version (Darwin)
-long machTicksPerSecond()
+long machTicksPerSecond() @nogc nothrow
 {
     // Be optimistic that ticksPerSecond (1e9*denom/numer) is integral. So far
     // so good on Darwin based platforms OS X, iOS.
diff --git a/libphobos/libdruntime/core/vararg.d b/libphobos/libdruntime/core/vararg.d
index 935b2bdb287..2c3e9659fb6 100644
--- a/libphobos/libdruntime/core/vararg.d
+++ b/libphobos/libdruntime/core/vararg.d
@@ -28,6 +28,8 @@  version (MIPS32)  version = MIPS_Any;
 version (MIPS64)  version = MIPS_Any;
 version (PPC)     version = PPC_Any;
 version (PPC64)   version = PPC_Any;
+version (RISCV32) version = RISCV_Any;
+version (RISCV64) version = RISCV_Any;
 
 version (ARM_Any)
 {
@@ -136,6 +138,21 @@  void va_arg()(ref va_list ap, TypeInfo ti, void* parmn)
         ap += tsize.alignUp;
         parmn[0..tsize] = p[0..tsize];
     }
+    else version (RISCV_Any)
+    {
+        const tsize = ti.tsize;
+        void* p;
+        if (tsize > (size_t.sizeof << 1))
+            p = *cast(void**) ap;
+        else
+        {
+            if (tsize == (size_t.sizeof << 1))
+                ap = ap.alignUp!(size_t.sizeof << 1);
+            p = cast(void*) ap;
+        }
+        ap += tsize.alignUp;
+        parmn[0..tsize] = p[0..tsize];
+    }
     else
         static assert(0, "Unsupported platform");
 }
diff --git a/libphobos/libdruntime/rt/critical_.d b/libphobos/libdruntime/rt/critical_.d
index ae181228b5c..36552a3ce1a 100644
--- a/libphobos/libdruntime/rt/critical_.d
+++ b/libphobos/libdruntime/rt/critical_.d
@@ -18,13 +18,13 @@  nothrow:
 
 import rt.monitor_, core.atomic;
 
-extern (C) void _d_critical_init()
+extern (C) void _d_critical_init() @nogc nothrow
 {
     initMutex(cast(Mutex*)&gcs.mtx);
     head = &gcs;
 }
 
-extern (C) void _d_critical_term()
+extern (C) void _d_critical_term() @nogc nothrow
 {
     // This function is only ever called by the runtime shutdown code
     // and therefore is single threaded so the following cast is fine.
diff --git a/libphobos/libdruntime/rt/dmain2.d b/libphobos/libdruntime/rt/dmain2.d
index 5ef26954890..0739b7451fd 100644
--- a/libphobos/libdruntime/rt/dmain2.d
+++ b/libphobos/libdruntime/rt/dmain2.d
@@ -62,22 +62,21 @@  struct UnitTestResult
     bool summarize;
 }
 
-extern (C) void _d_monitor_staticctor();
-extern (C) void _d_monitor_staticdtor();
-extern (C) void _d_critical_init();
-extern (C) void _d_critical_term();
+extern (C) void _d_monitor_staticctor() @nogc nothrow;
+extern (C) void _d_monitor_staticdtor() @nogc nothrow;
+extern (C) void _d_critical_init() @nogc nothrow;
+extern (C) void _d_critical_term() @nogc nothrow;
 extern (C) void gc_init();
 extern (C) void gc_term();
-extern (C) void thread_init() @nogc;
-extern (C) void thread_term() @nogc;
-extern (C) void lifetime_init();
+extern (C) void thread_init() @nogc nothrow;
+extern (C) void thread_term() @nogc nothrow;
 extern (C) void rt_moduleCtor();
 extern (C) void rt_moduleTlsCtor();
 extern (C) void rt_moduleDtor();
 extern (C) void rt_moduleTlsDtor();
 extern (C) void thread_joinAll();
 extern (C) UnitTestResult runModuleUnitTests();
-extern (C) void _d_initMonoTime();
+extern (C) void _d_initMonoTime() @nogc nothrow;
 
 version (CRuntime_Microsoft)
 {
@@ -134,7 +133,6 @@  extern (C) int rt_init()
         thread_init();
         // TODO: fixme - calls GC.addRange -> Initializes GC
         initStaticDataGC();
-        lifetime_init();
         rt_moduleCtor();
         rt_moduleTlsCtor();
         return 1;
diff --git a/libphobos/libdruntime/rt/lifetime.d b/libphobos/libdruntime/rt/lifetime.d
index 5a18968f6ee..18ecc31311c 100644
--- a/libphobos/libdruntime/rt/lifetime.d
+++ b/libphobos/libdruntime/rt/lifetime.d
@@ -40,9 +40,11 @@  private
     }
 }
 
-extern (C) void lifetime_init()
+// Now-removed symbol, kept around for ABI
+// Some programs are dynamically linked, so best to err on the side of keeping symbols around for a while (especially extern(C) ones)
+// https://github.com/dlang/druntime/pull/3361
+deprecated extern (C) void lifetime_init()
 {
-    // this is run before static ctors, so it is safe to modify immutables
 }
 
 /**
diff --git a/libphobos/libdruntime/rt/minfo.d b/libphobos/libdruntime/rt/minfo.d
index 0d5cd22b1aa..74891506364 100644
--- a/libphobos/libdruntime/rt/minfo.d
+++ b/libphobos/libdruntime/rt/minfo.d
@@ -58,7 +58,7 @@  struct ModuleGroup
     // target modules are involved in a cycle.
     //
     // The return value is malloc'd using C, so it must be freed after use.
-    private size_t[] genCyclePath(size_t srcidx, size_t targetidx, int[][] edges)
+    private size_t[] genCyclePath(size_t srcidx, size_t targetidx, int[][] edges) nothrow
     {
         import core.bitop : bt, btc, bts;
 
@@ -109,7 +109,7 @@  struct ModuleGroup
             // release mode.
             if (distance[target] != curdist)
             {
-                throw new Error("internal error printing module cycle");
+                assert(0, "internal error printing module cycle");
             }
 
             // determine the path. This is tricky, because we have to
@@ -162,14 +162,13 @@  struct ModuleGroup
      * Throws:
      *  Exception if it fails.
      */
-    void sortCtors(string cycleHandling)
+    void sortCtors(string cycleHandling) nothrow
     {
         import core.bitop : bts, btr, bt, BitRange;
         import core.internal.container.hashtab;
 
         enum OnCycle
         {
-            deprecate,
             abort,
             print,
             ignore
@@ -180,7 +179,9 @@  struct ModuleGroup
         switch (cycleHandling) with(OnCycle)
         {
         case "deprecate":
-            onCycle = deprecate;
+            import core.stdc.stdio : fprintf, stderr;
+            // Option deprecated in 2.101, remove in 2.111
+            fprintf(stderr, "`--DRT-oncycle=deprecate` is no longer supported, using `abort` instead\n");
             break;
         case "abort":
             onCycle = abort;
@@ -196,7 +197,7 @@  struct ModuleGroup
             break;
         default:
             // invalid cycle handling option.
-            throw new Error("DRT invalid cycle handling option: " ~ cycleHandling);
+            assert(0, "DRT invalid cycle handling option: " ~ cycleHandling);
         }
 
         debug (printModuleDependencies)
@@ -280,7 +281,7 @@  struct ModuleGroup
             .free(edges.ptr);
         }
 
-        void buildCycleMessage(size_t sourceIdx, size_t cycleIdx, scope void delegate(string) sink)
+        void buildCycleMessage(size_t sourceIdx, size_t cycleIdx, scope void delegate(string) nothrow sink)
         {
             version (Windows)
                 enum EOL = "\r\n";
@@ -312,7 +313,7 @@  struct ModuleGroup
         //
         // If a cycle is detected, returns the index of the module that completes the cycle.
         // Returns: true for success, false for a deprecated cycle error
-        bool findDeps(size_t idx, size_t* reachable)
+        bool findDeps(size_t idx, size_t* reachable) nothrow
         {
             static struct stackFrame
             {
@@ -356,14 +357,6 @@  struct ModuleGroup
                                 // was already started, this is a cycle.
                                 final switch (onCycle) with(OnCycle)
                                 {
-                                case deprecate:
-                                    // check with old algorithm
-                                    if (sortCtorsOld(edges))
-                                    {
-                                        // unwind to print deprecation message.
-                                        return false;   // deprecated cycle error
-                                    }
-                                    goto case abort; // fall through
                                 case abort:
 
                                     string errmsg = "";
@@ -418,7 +411,7 @@  struct ModuleGroup
         // ctor/dtors that must be dealt with. It recurses only when it finds
         // dependencies that also have static ctor/dtors.
         // Returns: true for success, false for a deprecated cycle error
-        bool processMod(size_t curidx)
+        bool processMod(size_t curidx) nothrow
         {
             immutable ModuleInfo* current = _modules[curidx];
 
@@ -461,7 +454,7 @@  struct ModuleGroup
         }
 
         // returns `false` if deprecated cycle error otherwise set `result`.
-        bool doSort(size_t relevantFlags, ref immutable(ModuleInfo)*[] result)
+        bool doSort(size_t relevantFlags, ref immutable(ModuleInfo)*[] result) nothrow
         {
             clearFlags(relevant);
             clearFlags(ctorstart);
@@ -533,193 +526,6 @@  struct ModuleGroup
         sortCtors(rt_configOption("oncycle"));
     }
 
-    /******************************
-     * This is the old ctor sorting algorithm that does not find all cycles.
-     *
-     * It is here to allow the deprecated behavior from the original algorithm
-     * until people have fixed their code.
-     *
-     * If no cycles are found, the _ctors and _tlsctors are replaced with the
-     * ones generated by this algorithm to preserve the old incorrect ordering
-     * behavior.
-     *
-     * Params:
-     *   edges = The module edges as found in the `importedModules` member of
-     *          each ModuleInfo. Generated in sortCtors.
-     * Returns:
-     *   true if no cycle is found, false if one was.
-     */
-    bool sortCtorsOld(int[][] edges)
-    {
-        immutable len = edges.length;
-        assert(len == _modules.length);
-
-        static struct StackRec
-        {
-            @property int mod()
-            {
-                return _mods[_idx];
-            }
-
-            int[] _mods;
-            size_t         _idx;
-        }
-
-        auto stack = (cast(StackRec*).calloc(len, StackRec.sizeof))[0 .. len];
-        // TODO: reuse GCBits by moving it to core.internal.container
-        immutable nwords = (len + 8 * size_t.sizeof - 1) / (8 * size_t.sizeof);
-        auto ctorstart = cast(size_t*).malloc(nwords * size_t.sizeof);
-        auto ctordone = cast(size_t*).malloc(nwords * size_t.sizeof);
-        int[] initialEdges = (cast(int *)malloc(int.sizeof * len))[0 .. len];
-        if (!stack.ptr || ctorstart is null || ctordone is null || !initialEdges.ptr)
-            assert(0);
-        scope (exit)
-        {
-            .free(stack.ptr);
-            .free(ctorstart);
-            .free(ctordone);
-            .free(initialEdges.ptr);
-        }
-
-        // initialize the initial edges
-        foreach (i, ref v; initialEdges)
-            v = cast(int)i;
-
-        bool sort(ref immutable(ModuleInfo)*[] ctors, uint mask)
-        {
-            import core.bitop;
-
-            ctors = (cast(immutable(ModuleInfo)**).malloc(len * size_t.sizeof))[0 .. len];
-            if (!ctors.ptr)
-                assert(0);
-
-            // clean flags
-            memset(ctorstart, 0, nwords * size_t.sizeof);
-            memset(ctordone, 0, nwords * size_t.sizeof);
-            size_t stackidx = 0;
-            size_t cidx;
-
-            int[] mods = initialEdges;
-
-            size_t idx;
-            while (true)
-            {
-                while (idx < mods.length)
-                {
-                    auto m = mods[idx];
-
-                    if (bt(ctordone, m))
-                    {
-                        // this module has already been processed, skip
-                        ++idx;
-                        continue;
-                    }
-                    else if (bt(ctorstart, m))
-                    {
-                        /* Trace back to the begin of the cycle.
-                         */
-                        bool ctorInCycle;
-                        size_t start = stackidx;
-                        while (start--)
-                        {
-                            auto sm = stack[start].mod;
-                            if (sm == m)
-                                break;
-                            assert(sm >= 0);
-                            if (bt(ctorstart, sm))
-                                ctorInCycle = true;
-                        }
-                        assert(stack[start].mod == m);
-                        if (ctorInCycle)
-                        {
-                            return false;
-                        }
-                        else
-                        {
-                            /* This is also a cycle, but the import chain does not constrain
-                             * the order of initialization, either because the imported
-                             * modules have no ctors or the ctors are standalone.
-                             */
-                            ++idx;
-                        }
-                    }
-                    else
-                    {
-                        auto curmod = _modules[m];
-                        if (curmod.flags & mask)
-                        {
-                            if (curmod.flags & MIstandalone || !edges[m].length)
-                            {   // trivial ctor => sort in
-                                ctors[cidx++] = curmod;
-                                bts(ctordone, m);
-                            }
-                            else
-                            {   // non-trivial ctor => defer
-                                bts(ctorstart, m);
-                            }
-                        }
-                        else    // no ctor => mark as visited
-                        {
-                            bts(ctordone, m);
-                        }
-
-                        if (edges[m].length)
-                        {
-                            /* Internal runtime error, recursion exceeds number of modules.
-                             */
-                            (stackidx < len) || assert(0);
-
-                            // recurse
-                            stack[stackidx++] = StackRec(mods, idx);
-                            idx  = 0;
-                            mods = edges[m];
-                        }
-                    }
-                }
-
-                if (stackidx)
-                {   // pop old value from stack
-                    --stackidx;
-                    mods    = stack[stackidx]._mods;
-                    idx     = stack[stackidx]._idx;
-                    auto m  = mods[idx++];
-                    if (bt(ctorstart, m) && !bts(ctordone, m))
-                        ctors[cidx++] = _modules[m];
-                }
-                else // done
-                    break;
-            }
-            // store final number and shrink array
-            ctors = (cast(immutable(ModuleInfo)**).realloc(ctors.ptr, cidx * size_t.sizeof))[0 .. cidx];
-            return true;
-        }
-
-        /* Do two passes: ctor/dtor, tlsctor/tlsdtor
-         */
-        immutable(ModuleInfo)*[] _ctors2;
-        immutable(ModuleInfo)*[] _tlsctors2;
-        auto result = sort(_ctors2, MIctor | MIdtor) && sort(_tlsctors2, MItlsctor | MItlsdtor);
-        if (result) // no cycle
-        {
-            // fall back to original ordering as part of the deprecation.
-            if (_ctors.ptr)
-                .free(_ctors.ptr);
-            _ctors = _ctors2;
-            if (_tlsctors.ptr)
-                .free(_tlsctors.ptr);
-            _tlsctors = _tlsctors2;
-        }
-        else
-        {
-            // free any allocated memory that will be forgotten
-            if (_ctors2.ptr)
-                .free(_ctors2.ptr);
-            if (_tlsctors2.ptr)
-                .free(_tlsctors2.ptr);
-        }
-        return result;
-    }
-
     void runCtors()
     {
         // run independent ctors
diff --git a/libphobos/libdruntime/rt/monitor_.d b/libphobos/libdruntime/rt/monitor_.d
index 0f1d0e97004..c1f3f3cb9a7 100644
--- a/libphobos/libdruntime/rt/monitor_.d
+++ b/libphobos/libdruntime/rt/monitor_.d
@@ -54,7 +54,7 @@  extern (C) void _d_monitordelete(Object h, bool det)
 }
 
 // does not call dispose events, for internal use only
-extern (C) void _d_monitordelete_nogc(Object h) @nogc
+extern (C) void _d_monitordelete_nogc(Object h) @nogc nothrow
 {
     auto m = getMonitor(h);
     if (m is null)
@@ -148,7 +148,7 @@  extern (C) void rt_detachDisposeEvent(Object h, DEvent e)
 
 nothrow:
 
-extern (C) void _d_monitor_staticctor()
+extern (C) void _d_monitor_staticctor() @nogc nothrow
 {
     version (Posix)
     {
@@ -158,7 +158,7 @@  extern (C) void _d_monitor_staticctor()
     initMutex(&gmtx);
 }
 
-extern (C) void _d_monitor_staticdtor()
+extern (C) void _d_monitor_staticdtor() @nogc nothrow
 {
     destroyMutex(&gmtx);
     version (Posix)
diff --git a/libphobos/src/MERGE b/libphobos/src/MERGE
index 30e9e80092f..a4daa8419bf 100644
--- a/libphobos/src/MERGE
+++ b/libphobos/src/MERGE
@@ -1,4 +1,4 @@ 
-1206fc94f967b0183667a109049cbf596deaa696
+a4a18d21c4ea7930f80309f85e38c571c5f6d4b8
 
 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/complex.d b/libphobos/src/std/complex.d
index 485b548b049..6b1541a2532 100644
--- a/libphobos/src/std/complex.d
+++ b/libphobos/src/std/complex.d
@@ -935,7 +935,7 @@  Complex!(CommonType!(T, U)) fromPolar(T, U)(const T modulus, const U argument)
     import std.math.operations : isClose;
     import std.math.algebraic : sqrt;
     import std.math.constants : PI_4;
-    auto z = fromPolar(core.math.sqrt(2.0), PI_4);
+    auto z = fromPolar(core.math.sqrt(2.0L), PI_4);
     assert(isClose(z.re, 1.0L));
     assert(isClose(z.im, 1.0L));
 }
diff --git a/libphobos/src/std/experimental/logger/core.d b/libphobos/src/std/experimental/logger/core.d
index efc4ef7f74a..d899db70793 100644
--- a/libphobos/src/std/experimental/logger/core.d
+++ b/libphobos/src/std/experimental/logger/core.d
@@ -12,56 +12,6 @@  import std.traits;
 
 import std.experimental.logger.filelogger;
 
-/** This template evaluates if the passed `LogLevel` is active.
-The previously described version statements are used to decide if the
-`LogLevel` is active. The version statements only influence the compile
-unit they are used with, therefore this function can only disable logging this
-specific compile unit.
-*/
-template isLoggingActiveAt(LogLevel ll)
-{
-    version (StdLoggerDisableLogging)
-    {
-        enum isLoggingActiveAt = false;
-    }
-    else
-    {
-        static if (ll == LogLevel.trace)
-        {
-            version (StdLoggerDisableTrace) enum isLoggingActiveAt = false;
-        }
-        else static if (ll == LogLevel.info)
-        {
-            version (StdLoggerDisableInfo) enum isLoggingActiveAt = false;
-        }
-        else static if (ll == LogLevel.warning)
-        {
-            version (StdLoggerDisableWarning) enum isLoggingActiveAt = false;
-        }
-        else static if (ll == LogLevel.error)
-        {
-            version (StdLoggerDisableError) enum isLoggingActiveAt = false;
-        }
-        else static if (ll == LogLevel.critical)
-        {
-            version (StdLoggerDisableCritical) enum isLoggingActiveAt = false;
-        }
-        else static if (ll == LogLevel.fatal)
-        {
-            version (StdLoggerDisableFatal) enum isLoggingActiveAt = false;
-        }
-        // If `isLoggingActiveAt` didn't get defined above to false,
-        // we default it to true.
-        static if (!is(typeof(isLoggingActiveAt) == bool))
-        {
-            enum isLoggingActiveAt = true;
-        }
-    }
-}
-
-/// This compile-time flag is `true` if logging is not statically disabled.
-enum isLoggingActive = isLoggingActiveAt!(LogLevel.all);
-
 /** This functions is used at runtime to determine if a `LogLevel` is
 active. The same previously defined version statements are used to disable
 certain levels. Again the version statements are associated with a compile
@@ -71,26 +21,6 @@  pure bool isLoggingEnabled()(LogLevel ll) @safe nothrow @nogc
 bool isLoggingEnabled()(LogLevel ll, LogLevel loggerLL,
     LogLevel globalLL, lazy bool condition = true) @safe
 {
-    switch (ll)
-    {
-        case LogLevel.trace:
-            version (StdLoggerDisableTrace) return false;
-            else break;
-        case LogLevel.info:
-            version (StdLoggerDisableInfo) return false;
-            else break;
-        case LogLevel.warning:
-            version (StdLoggerDisableWarning) return false;
-            else break;
-        case LogLevel.critical:
-            version (StdLoggerDisableCritical) return false;
-            else break;
-        case LogLevel.fatal:
-            version (StdLoggerDisableFatal) return false;
-            else break;
-        default: break;
-    }
-
     return ll >= globalLL
         && ll >= loggerLL
         && ll != LogLevel.off
@@ -99,66 +29,6 @@  bool isLoggingEnabled()(LogLevel ll, LogLevel loggerLL,
         && condition;
 }
 
-/** This template returns the `LogLevel` named "logLevel" of type $(D
-LogLevel) defined in a user defined module where the filename has the
-suffix "_loggerconfig.d". This `LogLevel` sets the minimal `LogLevel`
-of the module.
-
-A minimal `LogLevel` can be defined on a per module basis.
-In order to define a module `LogLevel` a file with a modulename
-"MODULENAME_loggerconfig" must be found. If no such module exists and the
-module is a nested module, it is checked if there exists a
-"PARENT_MODULE_loggerconfig" module with such a symbol.
-If this module exists and it contains a `LogLevel` called logLevel this $(D
-LogLevel) will be used. This parent lookup is continued until there is no
-parent module. Then the moduleLogLevel is `LogLevel.all`.
-*/
-template moduleLogLevel(string moduleName)
-if (!moduleName.length)
-{
-    // default
-    enum moduleLogLevel = LogLevel.all;
-}
-
-///
-@system unittest
-{
-    static assert(moduleLogLevel!"" == LogLevel.all);
-}
-
-/// ditto
-template moduleLogLevel(string moduleName)
-if (moduleName.length)
-{
-    import std.string : format;
-    mixin(q{
-        static if (__traits(compiles, {import %1$s : logLevel;}))
-        {
-            import %1$s : logLevel;
-            static assert(is(typeof(logLevel) : LogLevel),
-                          "Expect 'logLevel' to be of Type 'LogLevel'.");
-            // don't enforce enum here
-            alias moduleLogLevel = logLevel;
-        }
-        else
-            // use logLevel of package or default
-            alias moduleLogLevel = moduleLogLevel!(parentOf(moduleName));
-    }.format(moduleName ~ "_loggerconfig"));
-}
-
-///
-@system unittest
-{
-    static assert(moduleLogLevel!"not.amodule.path" == LogLevel.all);
-}
-
-private string parentOf(string mod)
-{
-    foreach_reverse (i, c; mod)
-        if (c == '.') return mod[0 .. i];
-    return null;
-}
-
 /* This function formates a `SysTime` into an `OutputRange`.
 
 The `SysTime` is formatted similar to
@@ -200,14 +70,8 @@  void log(int line = __LINE__, string file = __FILE__,
     lazy bool condition, lazy A args)
 if (args.length != 1)
 {
-    static if (isLoggingActive)
-    {
-        if (ll >= moduleLogLevel!moduleName)
-        {
-               stdThreadLocalLog.log!(line, file, funcName, prettyFuncName, moduleName)
-                (ll, condition, args);
-        }
-    }
+    stdThreadLocalLog.log!(line, file, funcName, prettyFuncName, moduleName)
+        (ll, condition, args);
 }
 
 /// Ditto
@@ -215,14 +79,8 @@  void log(T, string moduleName = __MODULE__)(const LogLevel ll,
     lazy bool condition, lazy T arg, int line = __LINE__, string file = __FILE__,
     string funcName = __FUNCTION__, string prettyFuncName = __PRETTY_FUNCTION__)
 {
-    static if (isLoggingActive)
-    {
-        if (ll >= moduleLogLevel!moduleName)
-        {
-            stdThreadLocalLog.log!(T,moduleName)(ll, condition, arg, line, file, funcName,
-                prettyFuncName);
-        }
-    }
+    stdThreadLocalLog.log!(T,moduleName)(ll, condition, arg, line, file, funcName,
+        prettyFuncName);
 }
 
 /** This function logs data.
@@ -244,14 +102,8 @@  void log(int line = __LINE__, string file = __FILE__,
     string moduleName = __MODULE__, A...)(const LogLevel ll, lazy A args)
 if (args.length > 1 && !is(Unqual!(A[0]) : bool))
 {
-    static if (isLoggingActive)
-    {
-        if (ll >= moduleLogLevel!moduleName)
-        {
-            stdThreadLocalLog.log!(line, file, funcName, prettyFuncName, moduleName)
-                (ll, args);
-        }
-    }
+    stdThreadLocalLog.log!(line, file, funcName, prettyFuncName, moduleName)
+        (ll, args);
 }
 
 /// Ditto
@@ -259,14 +111,8 @@  void log(T, string moduleName = __MODULE__)(const LogLevel ll, lazy T arg,
     int line = __LINE__, string file = __FILE__, string funcName = __FUNCTION__,
     string prettyFuncName = __PRETTY_FUNCTION__)
 {
-    static if (isLoggingActive)
-    {
-        if (ll >= moduleLogLevel!moduleName)
-        {
-            stdThreadLocalLog.log!T(ll, arg, line, file, funcName, prettyFuncName,
-                moduleName);
-        }
-    }
+    stdThreadLocalLog.log!T(ll, arg, line, file, funcName, prettyFuncName,
+        moduleName);
 }
 
 /** This function logs data.
@@ -289,11 +135,8 @@  void log(int line = __LINE__, string file = __FILE__,
     string moduleName = __MODULE__, A...)(lazy bool condition, lazy A args)
 if (args.length != 1)
 {
-    static if (isLoggingActive)
-    {
-        stdThreadLocalLog.log!(line, file, funcName, prettyFuncName, moduleName)
-            (stdThreadLocalLog.logLevel, condition, args);
-    }
+    stdThreadLocalLog.log!(line, file, funcName, prettyFuncName, moduleName)
+        (stdThreadLocalLog.logLevel, condition, args);
 }
 
 /// Ditto
@@ -301,11 +144,8 @@  void log(T, string moduleName = __MODULE__)(lazy bool condition, lazy T arg,
     int line = __LINE__, string file = __FILE__, string funcName = __FUNCTION__,
     string prettyFuncName = __PRETTY_FUNCTION__)
 {
-    static if (isLoggingActive)
-    {
-        stdThreadLocalLog.log!(T,moduleName)(stdThreadLocalLog.logLevel,
-            condition, arg, line, file, funcName, prettyFuncName);
-    }
+    stdThreadLocalLog.log!(T,moduleName)(stdThreadLocalLog.logLevel,
+        condition, arg, line, file, funcName, prettyFuncName);
 }
 
 /** This function logs data.
@@ -328,22 +168,16 @@  if ((args.length > 1 && !is(Unqual!(A[0]) : bool)
     && !is(Unqual!(A[0]) == LogLevel))
     || args.length == 0)
 {
-    static if (isLoggingActive)
-    {
-        stdThreadLocalLog.log!(line, file, funcName,
-           prettyFuncName, moduleName)(stdThreadLocalLog.logLevel, args);
-    }
+    stdThreadLocalLog.log!(line, file, funcName,
+       prettyFuncName, moduleName)(stdThreadLocalLog.logLevel, args);
 }
 
 void log(T)(lazy T arg, int line = __LINE__, string file = __FILE__,
     string funcName = __FUNCTION__, string prettyFuncName = __PRETTY_FUNCTION__,
     string moduleName = __MODULE__)
 {
-    static if (isLoggingActive)
-    {
-        stdThreadLocalLog.log!T(stdThreadLocalLog.logLevel, arg, line, file,
-            funcName, prettyFuncName, moduleName);
-    }
+    stdThreadLocalLog.log!T(stdThreadLocalLog.logLevel, arg, line, file,
+        funcName, prettyFuncName, moduleName);
 }
 
 /** This function logs data in a `printf`-style manner.
@@ -369,14 +203,8 @@  void logf(int line = __LINE__, string file = __FILE__,
     string moduleName = __MODULE__, A...)(const LogLevel ll,
     lazy bool condition, lazy string msg, lazy A args)
 {
-    static if (isLoggingActive)
-    {
-        if (ll >= moduleLogLevel!moduleName)
-        {
-            stdThreadLocalLog.logf!(line, file, funcName, prettyFuncName, moduleName)
-                (ll, condition, msg, args);
-        }
-    }
+    stdThreadLocalLog.logf!(line, file, funcName, prettyFuncName, moduleName)
+        (ll, condition, msg, args);
 }
 
 /** This function logs data in a `printf`-style manner.
@@ -400,14 +228,8 @@  void logf(int line = __LINE__, string file = __FILE__,
     string moduleName = __MODULE__, A...)(const LogLevel ll, lazy string msg,
         lazy A args)
 {
-    static if (isLoggingActive)
-    {
-        if (ll >= moduleLogLevel!moduleName)
-        {
-            stdThreadLocalLog.logf!(line, file, funcName, prettyFuncName, moduleName)
-                (ll, msg, args);
-        }
-    }
+    stdThreadLocalLog.logf!(line, file, funcName, prettyFuncName, moduleName)
+        (ll, msg, args);
 }
 
 /** This function logs data in a `printf`-style manner.
@@ -431,11 +253,8 @@  void logf(int line = __LINE__, string file = __FILE__,
     string moduleName = __MODULE__, A...)(lazy bool condition,
         lazy string msg, lazy A args)
 {
-    static if (isLoggingActive)
-    {
-        stdThreadLocalLog.logf!(line, file, funcName, prettyFuncName, moduleName)
-            (stdThreadLocalLog.logLevel, condition, msg, args);
-    }
+    stdThreadLocalLog.logf!(line, file, funcName, prettyFuncName, moduleName)
+        (stdThreadLocalLog.logLevel, condition, msg, args);
 }
 
 /** This function logs data in a `printf`-style manner.
@@ -457,11 +276,8 @@  void logf(int line = __LINE__, string file = __FILE__,
     string prettyFuncName = __PRETTY_FUNCTION__,
     string moduleName = __MODULE__, A...)(lazy string msg, lazy A args)
 {
-    static if (isLoggingActive)
-    {
-        stdThreadLocalLog.logf!(line, file, funcName,prettyFuncName, moduleName)
-            (stdThreadLocalLog.logLevel, msg, args);
-    }
+    stdThreadLocalLog.logf!(line, file, funcName,prettyFuncName, moduleName)
+        (stdThreadLocalLog.logLevel, msg, args);
 }
 
 /** This template provides the global log functions with the `LogLevel`
@@ -478,11 +294,8 @@  template defaultLogFunction(LogLevel ll)
         string moduleName = __MODULE__, A...)(lazy A args)
         if ((args.length > 0 && !is(Unqual!(A[0]) : bool)) || args.length == 0)
     {
-        static if (isLoggingActiveAt!ll && ll >= moduleLogLevel!moduleName)
-        {
             stdThreadLocalLog.memLogFunctions!(ll).logImpl!(line, file, funcName,
                 prettyFuncName, moduleName)(args);
-        }
     }
 
     void defaultLogFunction(int line = __LINE__, string file = __FILE__,
@@ -490,11 +303,8 @@  template defaultLogFunction(LogLevel ll)
         string prettyFuncName = __PRETTY_FUNCTION__,
         string moduleName = __MODULE__, A...)(lazy bool condition, lazy A args)
     {
-        static if (isLoggingActiveAt!ll && ll >= moduleLogLevel!moduleName)
-        {
-            stdThreadLocalLog.memLogFunctions!(ll).logImpl!(line, file, funcName,
-                prettyFuncName, moduleName)(condition, args);
-        }
+        stdThreadLocalLog.memLogFunctions!(ll).logImpl!(line, file, funcName,
+            prettyFuncName, moduleName)(condition, args);
     }
 }
 
@@ -551,11 +361,8 @@  template defaultLogFunctionf(LogLevel ll)
         string prettyFuncName = __PRETTY_FUNCTION__,
         string moduleName = __MODULE__, A...)(lazy string msg, lazy A args)
     {
-        static if (isLoggingActiveAt!ll && ll >= moduleLogLevel!moduleName)
-        {
-            stdThreadLocalLog.memLogFunctions!(ll).logImplf!(line, file, funcName,
-                prettyFuncName, moduleName)(msg, args);
-        }
+        stdThreadLocalLog.memLogFunctions!(ll).logImplf!(line, file, funcName,
+            prettyFuncName, moduleName)(msg, args);
     }
 
     void defaultLogFunctionf(int line = __LINE__, string file = __FILE__,
@@ -564,11 +371,8 @@  template defaultLogFunctionf(LogLevel ll)
         string moduleName = __MODULE__, A...)(lazy bool condition,
             lazy string msg, lazy A args)
     {
-        static if (isLoggingActiveAt!ll && ll >= moduleLogLevel!moduleName)
-        {
-            stdThreadLocalLog.memLogFunctions!(ll).logImplf!(line, file, funcName,
-                prettyFuncName, moduleName)(condition, msg, args);
-        }
+        stdThreadLocalLog.memLogFunctions!(ll).logImplf!(line, file, funcName,
+            prettyFuncName, moduleName)(condition, msg, args);
     }
 }
 
@@ -816,32 +620,23 @@  abstract class Logger
         Tid threadId, SysTime timestamp, Logger logger)
         @safe
     {
-        static if (isLoggingActive)
-        {
-            msgAppender = appender!string();
-            header = LogEntry(file, line, funcName, prettyFuncName,
-                moduleName, logLevel, threadId, timestamp, null, logger);
-        }
+        msgAppender = appender!string();
+        header = LogEntry(file, line, funcName, prettyFuncName,
+            moduleName, logLevel, threadId, timestamp, null, logger);
     }
 
     /** Logs a part of the log message. */
     protected void logMsgPart(scope const(char)[] msg) @safe
     {
-        static if (isLoggingActive)
-        {
-               msgAppender.put(msg);
-        }
+       msgAppender.put(msg);
     }
 
     /** Signals that the message has been written and no more calls to
     `logMsgPart` follow. */
     protected void finishLogMsg() @safe
     {
-        static if (isLoggingActive)
-        {
-            header.msg = msgAppender.data;
-            this.writeLogMsg(header);
-        }
+        header.msg = msgAppender.data;
+        this.writeLogMsg(header);
     }
 
     /** The `LogLevel` determines if the log call are processed or dropped
@@ -895,16 +690,13 @@  abstract class Logger
     */
     void forwardMsg(ref LogEntry payload) @trusted
     {
-        static if (isLoggingActive) synchronized (mutex)
+        if (isLoggingEnabled(payload.logLevel, this.logLevel_,
+            globalLogLevel))
         {
-            if (isLoggingEnabled(payload.logLevel, this.logLevel_,
-                globalLogLevel))
-            {
-                this.writeLogMsg(payload);
+            this.writeLogMsg(payload);
 
-                if (payload.logLevel == LogLevel.fatal)
-                    this.fatalHandler_();
-            }
+            if (payload.logLevel == LogLevel.fatal)
+                this.fatalHandler_();
         }
     }
 
@@ -944,8 +736,7 @@  abstract class Logger
             string moduleName = __MODULE__, A...)(lazy A args)
             if (args.length == 0 || (args.length > 0 && !is(A[0] : bool)))
         {
-            static if (isLoggingActiveAt!ll && ll >= moduleLogLevel!moduleName)
-                synchronized (mutex)
+            synchronized (mutex)
             {
                 if (isLoggingEnabled(ll, this.logLevel_, globalLogLevel))
                 {
@@ -991,8 +782,7 @@  abstract class Logger
             string moduleName = __MODULE__, A...)(lazy bool condition,
                 lazy A args)
         {
-            static if (isLoggingActiveAt!ll && ll >= moduleLogLevel!moduleName)
-                synchronized (mutex)
+            synchronized (mutex)
             {
                 if (isLoggingEnabled(ll, this.logLevel_, globalLogLevel,
                                      condition))
@@ -1040,8 +830,7 @@  abstract class Logger
             string moduleName = __MODULE__, A...)(lazy bool condition,
                 lazy string msg, lazy A args)
         {
-            static if (isLoggingActiveAt!ll && ll >= moduleLogLevel!moduleName)
-                synchronized (mutex)
+            synchronized (mutex)
             {
                 import std.format.write : formattedWrite;
 
@@ -1088,8 +877,7 @@  abstract class Logger
             string prettyFuncName = __PRETTY_FUNCTION__,
             string moduleName = __MODULE__, A...)(lazy string msg, lazy A args)
         {
-            static if (isLoggingActiveAt!ll && ll >= moduleLogLevel!moduleName)
-                synchronized (mutex)
+            synchronized (mutex)
             {
                 import std.format.write : formattedWrite;
 
@@ -1161,7 +949,7 @@  abstract class Logger
         lazy bool condition, lazy A args)
         if (args.length != 1)
     {
-        static if (isLoggingActive) synchronized (mutex)
+        synchronized (mutex)
         {
             if (isLoggingEnabled(ll, this.logLevel_, globalLogLevel, condition))
             {
@@ -1185,10 +973,9 @@  abstract class Logger
         string file = __FILE__, string funcName = __FUNCTION__,
         string prettyFuncName = __PRETTY_FUNCTION__)
     {
-        static if (isLoggingActive) synchronized (mutex)
+        synchronized (mutex)
         {
-            if (isLoggingEnabled(ll, this.logLevel_, globalLogLevel,
-                condition) && ll >= moduleLogLevel!moduleName)
+            if (isLoggingEnabled(ll, this.logLevel_, globalLogLevel, condition))
             {
                 this.beginLogMsg(file, line, funcName, prettyFuncName,
                     moduleName, ll, thisTid, Clock.currTime, this);
@@ -1230,7 +1017,7 @@  abstract class Logger
         string moduleName = __MODULE__, A...)(const LogLevel ll, lazy A args)
         if ((args.length > 1 && !is(Unqual!(A[0]) : bool)) || args.length == 0)
     {
-        static if (isLoggingActive) synchronized (mutex)
+        synchronized (mutex)
         {
             if (isLoggingEnabled(ll, this.logLevel_, globalLogLevel))
             {
@@ -1254,7 +1041,7 @@  abstract class Logger
         string prettyFuncName = __PRETTY_FUNCTION__,
         string moduleName = __MODULE__)
     {
-        static if (isLoggingActive) synchronized (mutex)
+        synchronized (mutex)
         {
             if (isLoggingEnabled(ll, this.logLevel_, globalLogLevel))
             {
@@ -1299,7 +1086,7 @@  abstract class Logger
         string moduleName = __MODULE__, A...)(lazy bool condition, lazy A args)
         if (args.length != 1)
     {
-        static if (isLoggingActive) synchronized (mutex)
+        synchronized (mutex)
         {
             if (isLoggingEnabled(this.logLevel_, this.logLevel_,
                 globalLogLevel, condition))
@@ -1324,7 +1111,7 @@  abstract class Logger
         string prettyFuncName = __PRETTY_FUNCTION__,
         string moduleName = __MODULE__)
     {
-        static if (isLoggingActive) synchronized (mutex)
+        synchronized (mutex)
         {
             if (isLoggingEnabled(this.logLevel_, this.logLevel_, globalLogLevel,
                 condition))
@@ -1371,7 +1158,7 @@  abstract class Logger
                 && !is(immutable A[0] == immutable LogLevel))
             || args.length == 0)
     {
-        static if (isLoggingActive) synchronized (mutex)
+        synchronized (mutex)
         {
             if (isLoggingEnabled(this.logLevel_, this.logLevel_,
                 globalLogLevel))
@@ -1395,7 +1182,7 @@  abstract class Logger
         string prettyFuncName = __PRETTY_FUNCTION__,
         string moduleName = __MODULE__)
     {
-        static if (isLoggingActive) synchronized (mutex)
+        synchronized (mutex)
         {
             if (isLoggingEnabled(this.logLevel_, this.logLevel_, globalLogLevel))
             {
@@ -1442,7 +1229,7 @@  abstract class Logger
         string moduleName = __MODULE__, A...)(const LogLevel ll,
         lazy bool condition, lazy string msg, lazy A args)
     {
-        static if (isLoggingActive) synchronized (mutex)
+        synchronized (mutex)
         {
             import std.format.write : formattedWrite;
 
@@ -1490,7 +1277,7 @@  abstract class Logger
         string moduleName = __MODULE__, A...)(const LogLevel ll,
             lazy string msg, lazy A args)
     {
-        static if (isLoggingActive) synchronized (mutex)
+        synchronized (mutex)
         {
             import std.format.write : formattedWrite;
 
@@ -1539,7 +1326,7 @@  abstract class Logger
         string moduleName = __MODULE__, A...)(lazy bool condition,
             lazy string msg, lazy A args)
     {
-        static if (isLoggingActive) synchronized (mutex)
+        synchronized (mutex)
         {
             import std.format.write : formattedWrite;
 
@@ -1585,7 +1372,7 @@  abstract class Logger
         string prettyFuncName = __PRETTY_FUNCTION__,
         string moduleName = __MODULE__, A...)(lazy string msg, lazy A args)
     {
-        static if (isLoggingActive) synchronized (mutex)
+        synchronized (mutex)
         {
             import std.format.write : formattedWrite;
 
diff --git a/libphobos/src/std/experimental/logger/package.d b/libphobos/src/std/experimental/logger/package.d
index 79245ec4767..89dc7131fb3 100644
--- a/libphobos/src/std/experimental/logger/package.d
+++ b/libphobos/src/std/experimental/logger/package.d
@@ -146,26 +146,6 @@  To gain more precise control over the logging process, additionally to
 overriding the `writeLogMsg` method the methods `beginLogMsg`,
 `logMsgPart` and `finishLogMsg` can be overridden.
 
-$(H3 Compile Time Disabling of `Logger`)
-In order to disable logging at compile time, pass `StdLoggerDisableLogging` as a
-version argument to the `D` compiler when compiling your program code.
-This will disable all logging functionality.
-Specific `LogLevel` can be disabled at compile time as well.
-In order to disable logging with the `trace` `LogLevel` pass
-`StdLoggerDisableTrace` as a version.
-The following table shows which version statement disables which
-`LogLevel`.
-$(TABLE
-    $(TR $(TD `LogLevel.trace` ) $(TD StdLoggerDisableTrace))
-    $(TR $(TD `LogLevel.info` ) $(TD StdLoggerDisableInfo))
-    $(TR $(TD `LogLevel.warning` ) $(TD StdLoggerDisableWarning))
-    $(TR $(TD `LogLevel.error` ) $(TD StdLoggerDisableError))
-    $(TR $(TD `LogLevel.critical` ) $(TD StdLoggerDisableCritical))
-    $(TR $(TD `LogLevel.fatal` ) $(TD StdLoggerDisableFatal))
-)
-Such a version statement will only disable logging in the associated compile
-unit.
-
 $(H3 Provided Logger)
 By default four `Logger` implementations are given. The `FileLogger`
 logs data to files. It can also be used to log to `stdout` and `stderr`
diff --git a/libphobos/src/std/file.d b/libphobos/src/std/file.d
index 6bc7d4d9113..05fad6724e0 100644
--- a/libphobos/src/std/file.d
+++ b/libphobos/src/std/file.d
@@ -3610,7 +3610,7 @@  version (StdDdoc)
             Throws:
                 $(LREF FileException) if the file does not exist.
         +/
-        this(string path);
+        this(return scope string path);
 
         version (Windows)
         {
@@ -3772,7 +3772,7 @@  else version (Windows)
     public:
         alias name this;
 
-        this(string path)
+        this(return scope string path)
         {
             import std.datetime.systime : FILETIMEToSysTime;
 
@@ -3881,7 +3881,7 @@  else version (Posix)
     public:
         alias name this;
 
-        this(string path)
+        this(return scope string path)
         {
             if (!path.exists)
                 throw new FileException(path, "File does not exist");
@@ -4424,7 +4424,7 @@  void rmdirRecurse(scope const(char)[] pathname) @safe
 }
 
 /// ditto
-void rmdirRecurse(ref DirEntry de) @safe
+void rmdirRecurse(ref scope DirEntry de) @safe
 {
     if (!de.isDir)
         throw new FileException(de.name, "Not a directory");
@@ -4459,7 +4459,7 @@  void rmdirRecurse(ref DirEntry de) @safe
 //"rmdirRecurse(in char[] pathname)" implementation. That is needlessly
 //expensive.
 //A DirEntry is a bit big (72B), so keeping the "by ref" signature is desirable.
-void rmdirRecurse(DirEntry de) @safe
+void rmdirRecurse(scope DirEntry de) @safe
 {
     rmdirRecurse(de);
 }
@@ -4511,22 +4511,20 @@  version (Posix) @system unittest
     enforce(!exists(deleteme));
 }
 
-@system unittest
+@safe unittest
 {
-    void[] buf;
-
-    buf = new void[10];
-    (cast(byte[]) buf)[] = 3;
+    ubyte[] buf = new ubyte[10];
+    buf[] = 3;
     string unit_file = deleteme ~ "-unittest_write.tmp";
     if (exists(unit_file)) remove(unit_file);
-    write(unit_file, buf);
+    write(unit_file, cast(void[]) buf);
     void[] buf2 = read(unit_file);
-    assert(buf == buf2);
+    assert(cast(void[]) buf == buf2);
 
     string unit2_file = deleteme ~ "-unittest_write2.tmp";
     copy(unit_file, unit2_file);
     buf2 = read(unit2_file);
-    assert(buf == buf2);
+    assert(cast(void[]) buf == buf2);
 
     remove(unit_file);
     assert(!exists(unit_file));
@@ -5042,7 +5040,7 @@  auto dirEntries(string path, string pattern, SpanMode mode,
     return filter!f(DirIterator(path, mode, followSymlink));
 }
 
-@system unittest
+@safe unittest
 {
     import std.stdio : writefln;
     immutable dpath = deleteme ~ "_dir";
@@ -5059,11 +5057,11 @@  auto dirEntries(string path, string pattern, SpanMode mode,
 
     mkdir(dpath);
     write(fpath, "hello world");
-    version (Posix)
+    version (Posix) () @trusted
     {
         core.sys.posix.unistd.symlink((dpath ~ '\0').ptr, (sdpath ~ '\0').ptr);
         core.sys.posix.unistd.symlink((fpath ~ '\0').ptr, (sfpath ~ '\0').ptr);
-    }
+    } ();
 
     static struct Flags { bool dir, file, link; }
     auto tests = [dpath : Flags(true), fpath : Flags(false, true)];
diff --git a/libphobos/src/std/math/algebraic.d b/libphobos/src/std/math/algebraic.d
index db70b7a5552..4791766ab3a 100644
--- a/libphobos/src/std/math/algebraic.d
+++ b/libphobos/src/std/math/algebraic.d
@@ -496,9 +496,9 @@  if (isFloatingPoint!T)
             [ 1.0L, 4.0L, 8.0L, 9.0L ],
             [ 4.0L, 4.0L, 7.0L, 9.0L ],
             [ 12.0L, 16.0L, 21.0L, 29.0L ],
-            [ 1e+8L, 1.0L, 1e-8L, 1e+8L ],
-            [ 1.0L, 1e+8L, 1e-8L, 1e+8L ],
-            [ 1e-8L, 1.0L, 1e+8L, 1e+8L ],
+            [ 1e+8L, 1.0L, 1e-8L, 1e+8L+5e-9L ],
+            [ 1.0L, 1e+8L, 1e-8L, 1e+8L+5e-9L ],
+            [ 1e-8L, 1.0L, 1e+8L, 1e+8L+5e-9L ],
             [ 1e-2L, 1e-4L, 1e-4L, 0.010000999950004999375L ],
             [ 2147483647.0L, 2147483647.0L, 2147483647.0L, 3719550785.027307813987L ]
         ];
diff --git a/libphobos/src/std/math/hardware.d b/libphobos/src/std/math/hardware.d
index 7bff07e86d4..40e42da74f9 100644
--- a/libphobos/src/std/math/hardware.d
+++ b/libphobos/src/std/math/hardware.d
@@ -674,9 +674,9 @@  nothrow @nogc:
         enum : ExceptionMask
         {
             inexactException      = 0x01,
-            divByZeroException    = 0x02,
-            underflowException    = 0x04,
-            overflowException     = 0x08,
+            divByZeroException    = 0x08,
+            underflowException    = 0x02,
+            overflowException     = 0x04,
             invalidException      = 0x10,
             severeExceptions   = overflowException | divByZeroException
                                  | invalidException,
diff --git a/libphobos/src/std/math/trigonometry.d b/libphobos/src/std/math/trigonometry.d
index 06a7cb10b35..a3d04c60402 100644
--- a/libphobos/src/std/math/trigonometry.d
+++ b/libphobos/src/std/math/trigonometry.d
@@ -467,20 +467,20 @@  private T tanImpl(T)(T x) @safe pure nothrow @nogc
         static immutable T[2][] vals =
         [
             // angle, tan
-            [   .5,  .54630248984],
-            [   1,   1.5574077247],
-            [   1.5, 14.101419947],
-            [   2,  -2.1850398633],
-            [   2.5,-.74702229724],
-            [   3,  -.14254654307],
-            [   3.5, .37458564016],
-            [   4,   1.1578212823],
-            [   4.5, 4.6373320546],
-            [   5,  -3.3805150062],
-            [   5.5,-.99558405221],
-            [   6,  -.29100619138],
-            [   6.5, .22027720035],
-            [   10,  .64836082746],
+            [   .5,  .546302489843790513255L],
+            [   1,   1.55740772465490223050L],
+            [   1.5, 14.1014199471717193876L],
+            [   2,  -2.18503986326151899164L],
+            [   2.5,-.747022297238660279355L],
+            [   3,  -.142546543074277805295L],
+            [   3.5, .374585640158594666330L],
+            [   4,   1.15782128234957758313L],
+            [   4.5, 4.63733205455118446831L],
+            [   5,  -3.38051500624658563698L],
+            [   5.5,-.995584052213885017701L],
+            [   6,  -.291006191384749157053L],
+            [   6.5, .220277200345896811825L],
+            [   10,  .648360827459086671259L],
 
             // special angles
             [   PI_4,   1],
@@ -857,11 +857,11 @@  private T atanImpl(T)(T x) @safe pure nothrow @nogc
         static immutable T[2][] vals =
         [
             // x, atan(x)
-            [ 0.25, 0.24497866313 ],
-            [ 0.5,  0.46364760900 ],
-            [ 1,    PI_4          ],
-            [ 1.5,  0.98279372325 ],
-            [ 10,   1.47112767430 ],
+            [ 0.25, 0.244978663126864154172L ],
+            [ 0.5,  0.463647609000806116214L ],
+            [ 1,    PI_4                     ],
+            [ 1.5,  0.982793723247329067985L ],
+            [ 10,   1.471127674303734591852L ],
         ];
 
         foreach (ref val; vals)
@@ -1075,10 +1075,10 @@  private T atan2Impl(T)(T y, T x) @safe pure nothrow @nogc
             [  3.0, -3.0,  3 * PI_4 ],
             [ -4.0, -4.0, -3 * PI_4 ],
 
-            [  0.75,  0.25,   1.249045772398 ],
-            [ -0.5,   0.375, -0.927295218002 ],
-            [  0.5,  -0.125,  1.815774989922 ],
-            [ -0.75, -0.5,   -2.158798930342 ],
+            [  0.75,  0.25,   1.2490457723982544258299L ],
+            [ -0.5,   0.375, -0.9272952180016122324285L ],
+            [  0.5,  -0.125,  1.8157749899217607734034L ],
+            [ -0.75, -0.5,   -2.1587989303424641704769L ],
         ];
 
         foreach (ref val; vals)
diff --git a/libphobos/src/std/numeric.d b/libphobos/src/std/numeric.d
index fd532b2ce40..96d20c233d8 100644
--- a/libphobos/src/std/numeric.d
+++ b/libphobos/src/std/numeric.d
@@ -79,10 +79,12 @@  public enum CustomFloatFlags
     none = 0
 }
 
+private enum isIEEEQuadruple = floatTraits!real.realFormat == RealFormat.ieeeQuadruple;
+
 private template CustomFloatParams(uint bits)
 {
     enum CustomFloatFlags flags = CustomFloatFlags.ieee
-                ^ ((bits == 80) ? CustomFloatFlags.storeNormalized : CustomFloatFlags.none);
+                ^ ((bits == 80 && !isIEEEQuadruple) ? CustomFloatFlags.storeNormalized : CustomFloatFlags.none);
     static if (bits ==  8) alias CustomFloatParams = CustomFloatParams!( 4,  3, flags);
     static if (bits == 16) alias CustomFloatParams = CustomFloatParams!(10,  5, flags);
     static if (bits == 32) alias CustomFloatParams = CustomFloatParams!(23,  8, flags);
@@ -367,11 +369,36 @@  private:
 public:
     static if (precision == 64) // CustomFloat!80 support hack
     {
-        ulong significand;
-        enum ulong significand_max = ulong.max;
-        mixin(bitfields!(
-            T_exp , "exponent", exponentWidth,
-            bool  , "sign"    , flags & flags.signed ));
+        static if (isIEEEQuadruple)
+        {
+        // Only use highest 64 significand bits from 112 explicitly stored
+        align (1):
+            enum ulong significand_max = ulong.max;
+            version (LittleEndian)
+            {
+                private ubyte[6] _padding; // 48-bit of padding
+                ulong significand;
+                mixin(bitfields!(
+                    T_exp , "exponent", exponentWidth,
+                    bool  , "sign"    , flags & flags.signed ));
+            }
+            else
+            {
+                mixin(bitfields!(
+                    T_exp , "exponent", exponentWidth,
+                    bool  , "sign"    , flags & flags.signed ));
+                ulong significand;
+                private ubyte[6] _padding; // 48-bit of padding
+            }
+        }
+        else
+        {
+            ulong significand;
+            enum ulong significand_max = ulong.max;
+            mixin(bitfields!(
+                T_exp , "exponent", exponentWidth,
+                bool  , "sign"    , flags & flags.signed ));
+        }
     }
     else
     {
@@ -631,23 +658,28 @@  public:
         auto x = F(0.125);
         assert(x.get!float == 0.125F);
         assert(x.get!double == 0.125);
+        assert(x.get!real == 0.125L);
 
         x -= 0.0625;
         assert(x.get!float == 0.0625F);
         assert(x.get!double == 0.0625);
+        assert(x.get!real == 0.0625L);
 
         x *= 2;
         assert(x.get!float == 0.125F);
         assert(x.get!double == 0.125);
+        assert(x.get!real == 0.125L);
 
         x /= 4;
         assert(x.get!float == 0.03125);
         assert(x.get!double == 0.03125);
+        assert(x.get!real == 0.03125L);
 
         x = 0.5;
         x ^^= 4;
         assert(x.get!float == 1 / 16.0F);
         assert(x.get!double == 1 / 16.0);
+        assert(x.get!real == 1 / 16.0L);
     }
 }
 
diff --git a/libphobos/src/std/stdio.d b/libphobos/src/std/stdio.d
index 1bde73d628d..8614dc96901 100644
--- a/libphobos/src/std/stdio.d
+++ b/libphobos/src/std/stdio.d
@@ -498,17 +498,21 @@  struct File
     private Impl* _p;
     private string _name;
 
-    package this(FILE* handle, string name, uint refs = 1, bool isPopened = false) @trusted
+    package this(FILE* handle, string name, uint refs = 1, bool isPopened = false) @trusted @nogc nothrow
     {
         import core.stdc.stdlib : malloc;
-        import std.exception : enforce;
 
         assert(!_p);
-        _p = cast(Impl*) enforce(malloc(Impl.sizeof), "Out of memory");
+        _p = cast(Impl*) malloc(Impl.sizeof);
+        if (!_p)
+        {
+            import core.exception : onOutOfMemoryError;
+            onOutOfMemoryError();
+        }
         initImpl(handle, name, refs, isPopened);
     }
 
-    private void initImpl(FILE* handle, string name, uint refs = 1, bool isPopened = false)
+    private void initImpl(FILE* handle, string name, uint refs = 1, bool isPopened = false) @nogc nothrow pure @safe
     {
         assert(_p);
         _p.handle = handle;
diff --git a/libphobos/src/std/sumtype.d b/libphobos/src/std/sumtype.d
index f3d3152b347..1d375ef4d7e 100644
--- a/libphobos/src/std/sumtype.d
+++ b/libphobos/src/std/sumtype.d
@@ -635,9 +635,19 @@  public:
 
                 this.match!destroyIfOwner;
 
-                mixin("Storage newStorage = { ",
-                    Storage.memberName!T, ": forward!rhs",
-                " };");
+                static if (isCopyable!T)
+                {
+                    // Workaround for https://issues.dlang.org/show_bug.cgi?id=21542
+                    mixin("Storage newStorage = { ",
+                        Storage.memberName!T, ": __ctfe ? rhs : forward!rhs",
+                    " };");
+                }
+                else
+                {
+                    mixin("Storage newStorage = { ",
+                        Storage.memberName!T, ": forward!rhs",
+                    " };");
+                }
 
                 storage = newStorage;
                 tag = tid;
@@ -678,7 +688,17 @@  public:
         {
             import core.lifetime : move;
 
-            rhs.match!((ref value) { this = move(value); });
+            rhs.match!((ref value) {
+                static if (isCopyable!(typeof(value)))
+                {
+                    // Workaround for https://issues.dlang.org/show_bug.cgi?id=21542
+                    this = __ctfe ? value : move(value);
+                }
+                else
+                {
+                    this = move(value);
+                }
+            });
             return this;
         }
     }
@@ -1569,6 +1589,28 @@  version (D_BetterC) {} else
     }
 }
 
+// Assignment of struct with overloaded opAssign in CTFE
+// https://issues.dlang.org/show_bug.cgi?id=23182
+@safe unittest
+{
+    static struct HasOpAssign
+    {
+        void opAssign(HasOpAssign rhs) {}
+    }
+
+    static SumType!HasOpAssign test()
+    {
+        SumType!HasOpAssign s;
+        // Test both overloads
+        s = HasOpAssign();
+        s = SumType!HasOpAssign();
+        return s;
+    }
+
+    // Force CTFE
+    enum result = test();
+}
+
 /// True if `T` is an instance of the `SumType` template, otherwise false.
 private enum bool isSumTypeInstance(T) = is(T == SumType!Args, Args...);
 
diff --git a/libphobos/testsuite/libphobos.cycles/cycles.exp b/libphobos/testsuite/libphobos.cycles/cycles.exp
index 80bdf0e85c9..fa3dfd4819a 100644
--- a/libphobos/testsuite/libphobos.cycles/cycles.exp
+++ b/libphobos/testsuite/libphobos.cycles/cycles.exp
@@ -23,7 +23,7 @@  set cycle_test_list [list \
     { ignore ""	 0 } \
     { abort "object.Error@.*: Cyclic dependency between module mod. and mod." 1 } \
     { print "Cyclic dependency between module mod. and mod." 0 } \
-    { deprecate "Deprecation 16211 warning:" 0 } \
+    { deprecate "deprecate is no longer supported, using abort instead" 1 } \
 ]
 
 # Initialize dg.