diff --git a/gcc/testsuite/gdc.test/compilable/covariant_override.d b/gcc/testsuite/gdc.test/compilable/covariant_override.d
new file mode 100644
index 00000000000..1afe0a28cfb
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/covariant_override.d
@@ -0,0 +1,34 @@
+// https://issues.dlang.org/show_bug.cgi?id=21538
+// REQUIRED_ARGS: -preview=dip1000
+
+interface I
+{
+    void f(void delegate() @safe dg) @safe;
+}
+
+class CI : I
+{
+    override void f(void delegate() @system dg) @safe { }
+}
+
+abstract class A
+{
+    void f(void delegate() @safe dg) @safe;
+}
+
+class CA : A
+{
+    override void f(void delegate() @system dg) @safe { }
+}
+
+// https://issues.dlang.org/show_bug.cgi?id=20904
+auto blah(void delegate())
+{
+}
+
+void delegate()[string] r;
+void main()
+{
+    void delegate() nothrow a;
+    r["v"] = a;
+}
diff --git a/gcc/testsuite/gdc.test/compilable/emptygenmain.d b/gcc/testsuite/gdc.test/compilable/emptygenmain.d
new file mode 100644
index 00000000000..be7bee83fa0
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/emptygenmain.d
@@ -0,0 +1,3 @@
+// REQUIRED_ARGS: -main -c
+
+void foo() { }
diff --git a/gcc/testsuite/gdc.test/compilable/noreturn1.d b/gcc/testsuite/gdc.test/compilable/noreturn1.d
index b041e072e9c..22734cf48b3 100644
--- a/gcc/testsuite/gdc.test/compilable/noreturn1.d
+++ b/gcc/testsuite/gdc.test/compilable/noreturn1.d
@@ -111,3 +111,15 @@ void* useTls()
     void* a3 = &globalNoreturn;
     return a1 < a2 ? a2 : a3;
 }
+
+/***************************************************/
+
+noreturn testfn(noreturn function() fn)
+{
+    fn();
+}
+
+noreturn testdg(noreturn delegate() dg)
+{
+    dg();
+}
diff --git a/gcc/testsuite/gdc.test/compilable/test17870.d b/gcc/testsuite/gdc.test/compilable/test17870.d
new file mode 100644
index 00000000000..2329b609170
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test17870.d
@@ -0,0 +1,26 @@
+alias AliasSeq(T...) = T;
+
+class A
+{
+    int z = 3;
+}
+
+class B : A
+{
+    int a = 1;
+}
+
+class C : B
+{
+    int b = 2;
+    alias tup = AliasSeq!(b, a, z);
+}
+
+void main()
+{
+    static const ins = new C;
+    static assert(&ins.tup[0] == &ins.b);
+    static assert(&ins.tup[1] == &ins.a);
+    static assert(&ins.tup[2] == &ins.z);
+    static assert(ins.tup == AliasSeq!(2,1,3));
+}
diff --git a/gcc/testsuite/gdc.test/compilable/test19873.d b/gcc/testsuite/gdc.test/compilable/test19873.d
new file mode 100644
index 00000000000..7252edd7520
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test19873.d
@@ -0,0 +1,37 @@
+// PERMUTE_ARGS -preview=dip1000
+// https://issues.dlang.org/show_bug.cgi?id=19873
+int* ed(scope int* x)
+{
+    auto y = x;
+    return y;
+}
+
+int* et(scope int* x) @trusted
+{
+    auto y = x;
+    return y;
+}
+
+int* es(scope int* x) @system
+{
+    auto y = x;
+    return y;
+}
+
+auto ad(scope int* x)
+{
+    auto y = x;
+    return y;
+}
+
+auto at(scope int* x) @trusted
+{
+    auto y = x;
+    return y;
+}
+
+auto as(scope int* x) @system
+{
+    auto y = x;
+    return y;
+}
diff --git a/gcc/testsuite/gdc.test/compilable/test21719.d b/gcc/testsuite/gdc.test/compilable/test21719.d
new file mode 100644
index 00000000000..9d444e16c78
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test21719.d
@@ -0,0 +1,21 @@
+// https://issues.dlang.org/show_bug.cgi?id=21719
+
+struct S
+{
+    auto f()
+    {
+    } // inferred to be @safe @nogc pure nothrow
+}
+
+class C
+{
+    auto f() // should also infer the same attributes
+    {
+    }
+}
+
+pure @nogc nothrow @safe void test(S s, C c)
+{
+    s.f;
+    c.f;
+}
diff --git a/gcc/testsuite/gdc.test/compilable/test22254.d b/gcc/testsuite/gdc.test/compilable/test22254.d
new file mode 100644
index 00000000000..94f6596a19d
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test22254.d
@@ -0,0 +1,19 @@
+// https://issues.dlang.org/show_bug.cgi?id=22254
+
+struct Template(T) { T t; }
+
+Template!Bar a;
+Template!Bar b;
+
+immutable struct Bar { }
+
+static assert(is(typeof(a) == typeof(b)));
+static assert(is(typeof(a) == Template!(immutable Bar)));
+
+Template!C c1;
+Template!C c2;
+
+immutable class C { }
+
+static assert(is(typeof(c1) == typeof(c2)));
+static assert(is(typeof(c1) == Template!(immutable C)));
diff --git a/gcc/testsuite/gdc.test/compilable/test22510.d b/gcc/testsuite/gdc.test/compilable/test22510.d
new file mode 100644
index 00000000000..af5d0a433eb
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test22510.d
@@ -0,0 +1,18 @@
+// https://issues.dlang.org/show_bug.cgi?id=22510
+
+struct S
+{
+	int b;
+
+    @disable this(this);
+    this (scope ref inout S) inout
+    {
+    	this.b = b;
+    }
+}
+
+void main()
+{
+	auto scoped_s = S(4);
+	auto heap_s = new S(42);
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/covariant_override.d b/gcc/testsuite/gdc.test/fail_compilation/covariant_override.d
new file mode 100644
index 00000000000..7738770775d
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/covariant_override.d
@@ -0,0 +1,35 @@
+/++
+https://issues.dlang.org/show_bug.cgi?id=21538
+
+TEST_OUTPUT:
+---
+fail_compilation/covariant_override.d(23): Error: function `@safe void covariant_override.CI.f(void delegate() @safe dg)` does not override any function, did you mean to override `@safe void covariant_override.I.f(void delegate() @system dg)`?
+fail_compilation/covariant_override.d(34): Error: function `@safe void covariant_override.CA.f(void delegate() @safe dg)` does not override any function, did you mean to override `@safe void covariant_override.A.f(void delegate() @system dg)`?
+fail_compilation/covariant_override.d(20): Error: class `covariant_override.CI` interface function `void f(void delegate() @system dg) @safe` is not implemented
+---
+++/
+
+static assert(!is(void delegate() @system : void delegate() @safe));
+static assert( is(void delegate() @safe : void delegate() @system));
+
+interface I
+{
+    void f(void delegate() @system dg) @safe;
+}
+
+class CI : I
+{
+    // this overrride should not be legal
+    override void f(void delegate() @safe dg) @safe { }
+}
+
+abstract class A
+{
+    void f(void delegate() @system dg) @safe;
+}
+
+class CA : A
+{
+    // this overrride should not be legal
+    override void f(void delegate() @safe dg) @safe { }
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail10964.d b/gcc/testsuite/gdc.test/fail_compilation/fail10964.d
index de3673f7860..4b31a92f9ab 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail10964.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail10964.d
@@ -5,8 +5,8 @@ fail_compilation/fail10964.d(28): Error: function `fail10964.S.__postblit` is no
 fail_compilation/fail10964.d(29): Error: function `fail10964.S.__postblit` is not `nothrow`
 fail_compilation/fail10964.d(30): Error: function `fail10964.S.__postblit` is not `nothrow`
 fail_compilation/fail10964.d(33): Error: function `fail10964.S.__postblit` is not `nothrow`
-fail_compilation/fail10964.d(34): Error: function `fail10964.S.__postblit` is not `nothrow`
-fail_compilation/fail10964.d(35): Error: function `fail10964.S.__postblit` is not `nothrow`
+fail_compilation/fail10964.d(34): Error: function `core.internal.array.construction._d_arraysetctor!(S[], S)._d_arraysetctor` is not `nothrow`
+fail_compilation/fail10964.d(35): Error: function `core.internal.array.construction._d_arrayctor!(S[], S)._d_arrayctor` is not `nothrow`
 fail_compilation/fail10964.d(22): Error: `nothrow` function `fail10964.foo` may throw
 ---
 */
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail10968.d b/gcc/testsuite/gdc.test/fail_compilation/fail10968.d
index 06e0687ce39..d9f554a4b78 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail10968.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail10968.d
@@ -1,24 +1,26 @@
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/fail10968.d(39): Error: `pure` function `fail10968.bar` cannot call impure function `fail10968.SA.__postblit`
-fail_compilation/fail10968.d(39): Error: `@safe` function `fail10968.bar` cannot call `@system` function `fail10968.SA.__postblit`
-fail_compilation/fail10968.d(27):        `fail10968.SA.__postblit` is declared here
-fail_compilation/fail10968.d(40): Error: `pure` function `fail10968.bar` cannot call impure function `fail10968.SA.__postblit`
-fail_compilation/fail10968.d(40): Error: `@safe` function `fail10968.bar` cannot call `@system` function `fail10968.SA.__postblit`
-fail_compilation/fail10968.d(27):        `fail10968.SA.__postblit` is declared here
 fail_compilation/fail10968.d(41): Error: `pure` function `fail10968.bar` cannot call impure function `fail10968.SA.__postblit`
 fail_compilation/fail10968.d(41): Error: `@safe` function `fail10968.bar` cannot call `@system` function `fail10968.SA.__postblit`
-fail_compilation/fail10968.d(27):        `fail10968.SA.__postblit` is declared here
-fail_compilation/fail10968.d(44): Error: `pure` function `fail10968.bar` cannot call impure function `fail10968.SA.__postblit`
-fail_compilation/fail10968.d(44): Error: `@safe` function `fail10968.bar` cannot call `@system` function `fail10968.SA.__postblit`
-fail_compilation/fail10968.d(27):        `fail10968.SA.__postblit` is declared here
-fail_compilation/fail10968.d(45): Error: `pure` function `fail10968.bar` cannot call impure function `fail10968.SA.__postblit`
-fail_compilation/fail10968.d(45): Error: `@safe` function `fail10968.bar` cannot call `@system` function `fail10968.SA.__postblit`
-fail_compilation/fail10968.d(27):        `fail10968.SA.__postblit` is declared here
+fail_compilation/fail10968.d(29):        `fail10968.SA.__postblit` is declared here
+fail_compilation/fail10968.d(42): Error: `pure` function `fail10968.bar` cannot call impure function `fail10968.SA.__postblit`
+fail_compilation/fail10968.d(42): Error: `@safe` function `fail10968.bar` cannot call `@system` function `fail10968.SA.__postblit`
+fail_compilation/fail10968.d(29):        `fail10968.SA.__postblit` is declared here
+fail_compilation/fail10968.d(43): Error: `pure` function `fail10968.bar` cannot call impure function `fail10968.SA.__postblit`
+fail_compilation/fail10968.d(43): Error: `@safe` function `fail10968.bar` cannot call `@system` function `fail10968.SA.__postblit`
+fail_compilation/fail10968.d(29):        `fail10968.SA.__postblit` is declared here
 fail_compilation/fail10968.d(46): Error: `pure` function `fail10968.bar` cannot call impure function `fail10968.SA.__postblit`
 fail_compilation/fail10968.d(46): Error: `@safe` function `fail10968.bar` cannot call `@system` function `fail10968.SA.__postblit`
-fail_compilation/fail10968.d(27):        `fail10968.SA.__postblit` is declared here
+fail_compilation/fail10968.d(29):        `fail10968.SA.__postblit` is declared here
+fail_compilation/fail10968.d(47): Error: `pure` function `fail10968.bar` cannot call impure function `fail10968.SA.__postblit`
+fail_compilation/fail10968.d(47): Error: `@safe` function `fail10968.bar` cannot call `@system` function `fail10968.SA.__postblit`
+fail_compilation/fail10968.d(29):        `fail10968.SA.__postblit` is declared here
+fail_compilation/fail10968.d(47): Error: `pure` function `fail10968.bar` cannot call impure function `core.internal.array.construction._d_arraysetctor!(SA[], SA)._d_arraysetctor`
+fail_compilation/fail10968.d(48): Error: `pure` function `fail10968.bar` cannot call impure function `fail10968.SA.__postblit`
+fail_compilation/fail10968.d(48): Error: `@safe` function `fail10968.bar` cannot call `@system` function `fail10968.SA.__postblit`
+fail_compilation/fail10968.d(29):        `fail10968.SA.__postblit` is declared here
+fail_compilation/fail10968.d(48): Error: `pure` function `fail10968.bar` cannot call impure function `core.internal.array.construction._d_arrayctor!(SA[], SA)._d_arrayctor`
 ---
 */
 
@@ -49,12 +51,12 @@ void bar() pure @safe
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/fail10968.d(72): Error: struct `fail10968.SD` is not copyable because it has a disabled postblit
-fail_compilation/fail10968.d(73): Error: struct `fail10968.SD` is not copyable because it has a disabled postblit
 fail_compilation/fail10968.d(74): Error: struct `fail10968.SD` is not copyable because it has a disabled postblit
-fail_compilation/fail10968.d(77): Error: struct `fail10968.SD` is not copyable because it has a disabled postblit
-fail_compilation/fail10968.d(78): Error: struct `fail10968.SD` is not copyable because it has a disabled postblit
+fail_compilation/fail10968.d(75): Error: struct `fail10968.SD` is not copyable because it has a disabled postblit
+fail_compilation/fail10968.d(76): Error: struct `fail10968.SD` is not copyable because it has a disabled postblit
 fail_compilation/fail10968.d(79): Error: struct `fail10968.SD` is not copyable because it has a disabled postblit
+fail_compilation/fail10968.d(80): Error: struct `fail10968.SD` is not copyable because it has a disabled postblit
+fail_compilation/fail10968.d(81): Error: struct `fail10968.SD` is not copyable because it has a disabled postblit
 ---
 */
 
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail16997.d b/gcc/testsuite/gdc.test/fail_compilation/fail16997.d
index a8f3ae453db..279d9da6dfc 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail16997.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail16997.d
@@ -1,25 +1,25 @@
 /*
-REQUIRED_ARGS: -de
+REQUIRED_ARGS: -de -revert=intpromote
 TEST_OUTPUT:
 ---
-fail_compilation/fail16997.d(31): Deprecation: integral promotion not done for `~c`, use '-preview=intpromote' switch or `~cast(int)(c)`
-fail_compilation/fail16997.d(32): Deprecation: integral promotion not done for `-c`, use '-preview=intpromote' switch or `-cast(int)(c)`
-fail_compilation/fail16997.d(33): Deprecation: integral promotion not done for `+c`, use '-preview=intpromote' switch or `+cast(int)(c)`
-fail_compilation/fail16997.d(36): Deprecation: integral promotion not done for `~w`, use '-preview=intpromote' switch or `~cast(int)(w)`
-fail_compilation/fail16997.d(37): Deprecation: integral promotion not done for `-w`, use '-preview=intpromote' switch or `-cast(int)(w)`
-fail_compilation/fail16997.d(38): Deprecation: integral promotion not done for `+w`, use '-preview=intpromote' switch or `+cast(int)(w)`
-fail_compilation/fail16997.d(41): Deprecation: integral promotion not done for `~sb`, use '-preview=intpromote' switch or `~cast(int)(sb)`
-fail_compilation/fail16997.d(42): Deprecation: integral promotion not done for `-sb`, use '-preview=intpromote' switch or `-cast(int)(sb)`
-fail_compilation/fail16997.d(43): Deprecation: integral promotion not done for `+sb`, use '-preview=intpromote' switch or `+cast(int)(sb)`
-fail_compilation/fail16997.d(46): Deprecation: integral promotion not done for `~ub`, use '-preview=intpromote' switch or `~cast(int)(ub)`
-fail_compilation/fail16997.d(47): Deprecation: integral promotion not done for `-ub`, use '-preview=intpromote' switch or `-cast(int)(ub)`
-fail_compilation/fail16997.d(48): Deprecation: integral promotion not done for `+ub`, use '-preview=intpromote' switch or `+cast(int)(ub)`
-fail_compilation/fail16997.d(51): Deprecation: integral promotion not done for `~s`, use '-preview=intpromote' switch or `~cast(int)(s)`
-fail_compilation/fail16997.d(52): Deprecation: integral promotion not done for `-s`, use '-preview=intpromote' switch or `-cast(int)(s)`
-fail_compilation/fail16997.d(53): Deprecation: integral promotion not done for `+s`, use '-preview=intpromote' switch or `+cast(int)(s)`
-fail_compilation/fail16997.d(56): Deprecation: integral promotion not done for `~us`, use '-preview=intpromote' switch or `~cast(int)(us)`
-fail_compilation/fail16997.d(57): Deprecation: integral promotion not done for `-us`, use '-preview=intpromote' switch or `-cast(int)(us)`
-fail_compilation/fail16997.d(58): Deprecation: integral promotion not done for `+us`, use '-preview=intpromote' switch or `+cast(int)(us)`
+fail_compilation/fail16997.d(31): Deprecation: integral promotion not done for `~c`, remove '-revert=intpromote' switch or `~cast(int)(c)`
+fail_compilation/fail16997.d(32): Deprecation: integral promotion not done for `-c`, remove '-revert=intpromote' switch or `-cast(int)(c)`
+fail_compilation/fail16997.d(33): Deprecation: integral promotion not done for `+c`, remove '-revert=intpromote' switch or `+cast(int)(c)`
+fail_compilation/fail16997.d(36): Deprecation: integral promotion not done for `~w`, remove '-revert=intpromote' switch or `~cast(int)(w)`
+fail_compilation/fail16997.d(37): Deprecation: integral promotion not done for `-w`, remove '-revert=intpromote' switch or `-cast(int)(w)`
+fail_compilation/fail16997.d(38): Deprecation: integral promotion not done for `+w`, remove '-revert=intpromote' switch or `+cast(int)(w)`
+fail_compilation/fail16997.d(41): Deprecation: integral promotion not done for `~sb`, remove '-revert=intpromote' switch or `~cast(int)(sb)`
+fail_compilation/fail16997.d(42): Deprecation: integral promotion not done for `-sb`, remove '-revert=intpromote' switch or `-cast(int)(sb)`
+fail_compilation/fail16997.d(43): Deprecation: integral promotion not done for `+sb`, remove '-revert=intpromote' switch or `+cast(int)(sb)`
+fail_compilation/fail16997.d(46): Deprecation: integral promotion not done for `~ub`, remove '-revert=intpromote' switch or `~cast(int)(ub)`
+fail_compilation/fail16997.d(47): Deprecation: integral promotion not done for `-ub`, remove '-revert=intpromote' switch or `-cast(int)(ub)`
+fail_compilation/fail16997.d(48): Deprecation: integral promotion not done for `+ub`, remove '-revert=intpromote' switch or `+cast(int)(ub)`
+fail_compilation/fail16997.d(51): Deprecation: integral promotion not done for `~s`, remove '-revert=intpromote' switch or `~cast(int)(s)`
+fail_compilation/fail16997.d(52): Deprecation: integral promotion not done for `-s`, remove '-revert=intpromote' switch or `-cast(int)(s)`
+fail_compilation/fail16997.d(53): Deprecation: integral promotion not done for `+s`, remove '-revert=intpromote' switch or `+cast(int)(s)`
+fail_compilation/fail16997.d(56): Deprecation: integral promotion not done for `~us`, remove '-revert=intpromote' switch or `~cast(int)(us)`
+fail_compilation/fail16997.d(57): Deprecation: integral promotion not done for `-us`, remove '-revert=intpromote' switch or `-cast(int)(us)`
+fail_compilation/fail16997.d(58): Deprecation: integral promotion not done for `+us`, remove '-revert=intpromote' switch or `+cast(int)(us)`
 ---
 */
 
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail809.d b/gcc/testsuite/gdc.test/fail_compilation/fail809.d
deleted file mode 100644
index b83639b0d08..00000000000
--- a/gcc/testsuite/gdc.test/fail_compilation/fail809.d
+++ /dev/null
@@ -1,12 +0,0 @@
-// REQUIRED_ARGS: -preview=dip1000
-/*
-TEST_OUTPUT:
----
-fail_compilation/fail809.d(11): Error: scope variable `dg_` may not be returned
----
-*/
-int delegate() test(lazy int dg)
-{
-    int delegate() dg_ = &dg;
-    return dg_;
-}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fob2.d b/gcc/testsuite/gdc.test/fail_compilation/fob2.d
index dbe8ea2f883..175ade3cafc 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fob2.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fob2.d
@@ -120,7 +120,7 @@ fail_compilation/fob2.d(515): Error: variable `fob2.test52.p` has undefined stat
 }
 
 
-@live void test52()
+@live void test52() @safe
 {
     int x = 5;
     auto p = &x;
diff --git a/gcc/testsuite/gdc.test/fail_compilation/imports/test20023b.d b/gcc/testsuite/gdc.test/fail_compilation/imports/test20023b.d
new file mode 100644
index 00000000000..c3e8a78e98d
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/imports/test20023b.d
@@ -0,0 +1,10 @@
+module imports.test20023b;
+
+auto threw()() @safe
+{
+    try
+        throw new Exception("Hello");
+    catch (Exception e)
+        return e;
+    assert(0);
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/retscope.d b/gcc/testsuite/gdc.test/fail_compilation/retscope.d
index 58f0430f5ad..64db4c81196 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/retscope.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/retscope.d
@@ -14,14 +14,14 @@ fail_compilation/retscope.d(49): Error: address of struct temporary returned by
 
 
 
-int* foo1(return scope int* p) { return p; } // ok
+int* foo1(return scope int* p) @safe { return p; } // ok
 
-int* foo2()(scope int* p) { return p; }  // ok, 'return' is inferred
+int* foo2()(scope int* p) @safe { return p; }  // ok, 'return' is inferred
 alias foo2a = foo2!();
 
-int* foo3(scope int* p) { return p; }   // error
+int* foo3(scope int* p) @safe { return p; }   // error
 
-int* foo4(bool b)
+int* foo4(bool b) @safe
 {
     int i;
     int j;
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test15191.d b/gcc/testsuite/gdc.test/fail_compilation/test15191.d
index 173473a6675..1b3078ff051 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/test15191.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/test15191.d
@@ -1,18 +1,52 @@
 /* TEST_OUTPUT:
+PERMUTE_ARGS -dip1000
 ---
-fail_compilation/test15191.d(17): Error: cannot take address of `ref return` of `foo()` in `@safe` function `bar`
+fail_compilation/test15191.d(31): Error: returning `&identity(x)` escapes a reference to local variable `x`
+fail_compilation/test15191.d(37): Error: returning `&identityPtr(x)` escapes a reference to local variable `x`
+fail_compilation/test15191.d(43): Error: cannot take address of `ref return` of `identityPtr()` in `@safe` function `addrOfRefTransitive`
+fail_compilation/test15191.d(43): Error: returning `&identityPtr(x)` escapes a reference to local variable `x`
 ---
 */
 
-
 // https://issues.dlang.org/show_bug.cgi?id=15191
+// https://issues.dlang.org/show_bug.cgi?id=22519
 
-ref int foo(return ref int s)@safe
+@safe:
+ref int foo(return ref int s)
 {
     return s;
 }
 
-int* bar(return ref int s) @safe
+int* bar(return ref int s)
 {
     return &foo(s);
 }
+
+ref int identity(ref return int x) {return x;}
+ref int* identityPtr(ref return int* x) {return x;}
+
+int* addrOfRefEscape()
+{
+	int x;
+	return &identity(x);
+}
+
+int** addrOfRefSystem() @system
+{
+	int* x;
+	return &identityPtr(x);
+}
+
+int** addrOfRefTransitive()
+{
+	int* x;
+	return &identityPtr(x);
+}
+
+int gInt;
+ref int getGlobalInt() {return gInt;}
+
+int* addrOfRefGlobal()
+{
+	return &getGlobalInt();
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test17977.d b/gcc/testsuite/gdc.test/fail_compilation/test17977.d
new file mode 100644
index 00000000000..ff6bc1c44f4
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/test17977.d
@@ -0,0 +1,20 @@
+/*
+https://issues.dlang.org/show_bug.cgi?id=15399
+REQUIRED_ARGS: -preview=dip1000
+TEST_OUTPUT:
+---
+fail_compilation/test17977.d(19): Error: address of variable `__slList3` assigned to `elem` with longer lifetime
+---
+*/
+
+@safe:
+struct List {
+    int* data;
+    ~this();
+    int* front() return;
+}
+
+void test()
+{
+    auto elem = List().front;
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test20023.d b/gcc/testsuite/gdc.test/fail_compilation/test20023.d
new file mode 100644
index 00000000000..909e699d3b5
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/test20023.d
@@ -0,0 +1,16 @@
+// REQUIRED_ARGS: -preview=dip1000 -preview=dip1008 -Ifail_compilation/extra-files
+// https://issues.dlang.org/show_bug.cgi?id=20023
+/*
+TEST_OUTPUT:
+---
+fail_compilation/imports/test20023b.d(8): Error: scope variable `e` may not be returned
+fail_compilation/test20023.d(15): Error: template instance `imports.test20023b.threw!()` error instantiating
+---
+*/
+import imports.test20023b;
+
+@safe:
+void main()
+{
+    threw!()();
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/traits_initSymbol.d b/gcc/testsuite/gdc.test/fail_compilation/traits_initSymbol.d
new file mode 100644
index 00000000000..94ff80ad551
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/traits_initSymbol.d
@@ -0,0 +1,63 @@
+/********************************************
+TEST_OUTPUT:
+---
+fail_compilation/traits_initSymbol.d(105): Error: struct / class type expected as argument to __traits(initSymbol) instead of `int`
+fail_compilation/traits_initSymbol.d(106): Error: struct / class type expected as argument to __traits(initSymbol) instead of `S[2]`
+fail_compilation/traits_initSymbol.d(107): Error: struct / class type expected as argument to __traits(initSymbol) instead of `123`
+---
+*/
+#line 100
+
+struct S { int i = 4; }
+
+void test1()
+{
+    const void[] initInt   = __traits(initSymbol, int);
+    const void[] initArray = __traits(initSymbol, S[2]);
+    const void[] initValue = __traits(initSymbol, 123);
+}
+
+/********************************************
+TEST_OUTPUT:
+---
+fail_compilation/traits_initSymbol.d(203): Error: cannot determine the address of the initializer symbol during CTFE
+fail_compilation/traits_initSymbol.d(203):        called from here: `(*function () pure nothrow @nogc @safe => S)()`
+---
+*/
+#line 200
+
+void test2()
+{
+    enum initLen = (() => __traits(initSymbol, S))();
+}
+
+/********************************************
+TEST_OUTPUT:
+---
+fail_compilation/traits_initSymbol.d(305): Error: struct / class type expected as argument to __traits(initSymbol) instead of `traits_initSymbol.Interface`
+---
+*/
+#line 300
+
+interface Interface {}
+
+void test3()
+{
+    const void[] initInterface = __traits(initSymbol, Interface);
+}
+
+/********************************************
+TEST_OUTPUT:
+---
+fail_compilation/traits_initSymbol.d(404): Error: expected 1 arguments for `initSymbol` but had 0
+fail_compilation/traits_initSymbol.d(405): Error: expected 1 arguments for `initSymbol` but had 2
+---
+*/
+#line 400
+
+
+void test4()
+{
+    const void[] tmp = __traits(initSymbol);
+    const void[] tmo = __traits(initSymbol, Interface, S);
+}
diff --git a/gcc/testsuite/gdc.test/runnable/b19294.d b/gcc/testsuite/gdc.test/runnable/b19294.d
new file mode 100644
index 00000000000..5700195ccb8
--- /dev/null
+++ b/gcc/testsuite/gdc.test/runnable/b19294.d
@@ -0,0 +1,163 @@
+alias T = MyStruct!float;
+
+struct MyStruct(U)
+{
+    U x;
+    U y;
+
+    this(U xx, U yy)
+    {
+        x = xx;
+        y = yy;
+    }
+
+    MyStruct!U opBinary(string op)(MyStruct!U z) const
+    {
+        alias C = typeof(return);
+        auto w = C(this.x, this.y);
+        return w.opOpAssign!(op)(z);
+    }
+
+    MyStruct!U opBinaryRight(string op)(MyStruct!U z) const
+    {
+        return opBinary!(op)(z);
+    }
+
+    ref MyStruct opOpAssign(string op, U)(const MyStruct!U z)
+    {
+        mixin ("x "~op~"= z.x;");
+        mixin ("y "~op~"= z.y;");
+        return this;
+    }
+
+    MyStruct!U opBinary(string op, R)(R z) const
+        if (is(R == int) || is(R == float))
+    {
+        alias C = typeof(return);
+        auto w = C(this.x, this.y);
+        return w.opOpAssign!(op)(z);
+    }
+
+    MyStruct!U opBinaryRight(string op, R)(R z) const
+        if (is(R == int) || is(R == float))
+    {
+        return opBinary!(op)(z);
+    }
+
+    ref MyStruct opOpAssign(string op, R)(const R z)
+        if (is(R == int) || is(R == float))
+    {
+        mixin ("x "~op~"= z;");
+        return this;
+    }
+}
+
+void main()
+{
+    T c = MyStruct!float(1.0f, 1.0f);
+    T[] arr = [T(1,1), T(2,2), T(3,3), T(4,4), T(5,5), T(6,6)];
+    T[] result = new T[arr.length];
+
+    // part 2
+
+    result[0] = c * c;
+    assert(result[0] == T(1, 1));
+
+    result[0] = arr[1] * arr[2];
+    assert(result[0] == T(6, 6));
+
+    int[] intarr = [6, 5, 4, 3, 2, 1];
+
+    result[] = arr[] * arr[];
+    assert(result[] == [T(1, 1), T(4, 4), T(9, 9), T(16, 16), T(25, 25), T(36, 36)]);
+
+    result[] = arr[] * 3;
+    assert(result[] == [T(3, 1), T(6, 2), T(9, 3), T(12, 4), T(15, 5), T(18, 6)]);
+    result[] = 3 * arr[];
+    assert(result[] == [T(3, 1), T(6, 2), T(9, 3), T(12, 4), T(15, 5), T(18, 6)]);
+
+    result[] = arr[];
+    result[1..3] = arr[1..3] * 2.0f;
+    assert(result[] == [T(1, 1), T(4, 2), T(6, 3), T(4, 4), T(5, 5), T(6, 6)]);
+    result[1..3] = 2.0f * arr[1..3];
+    assert(result[] == [T(1, 1), T(4, 2), T(6, 3), T(4, 4), T(5, 5), T(6, 6)]);
+
+    result[] = arr[];
+    result[1..$] = arr[1..$] * 2.0f;
+    assert(result[] == [T(1, 1), T(4, 2), T(6, 3), T(8, 4), T(10, 5), T(12, 6)]);
+    result[1..$] = 2.0f * arr[1..$];
+    assert(result[] == [T(1, 1), T(4, 2), T(6, 3), T(8, 4), T(10, 5), T(12, 6)]);
+
+    result[] = intarr[] * arr[];
+    assert(result[] == [T(6, 1), T(10, 2), T(12, 3), T(12, 4), T(10, 5), T(6, 6)]);
+    result[] = arr[] * intarr[];
+    assert(result[] == [T(6, 1), T(10, 2), T(12, 3), T(12, 4), T(10, 5), T(6, 6)]);
+
+    result[] = intarr[] * T(2,3);
+    assert(result[] == [T(12, 3), T(10, 3), T(8, 3), T(6, 3), T(4, 3), T(2, 3)]);
+    result[] = T(2,3) * intarr[];
+    assert(result[] == [T(12, 3), T(10, 3), T(8, 3), T(6, 3), T(4, 3), T(2, 3)]);
+
+    result[] = intarr[] * c;
+    assert(result[] == [T(6, 1), T(5, 1), T(4, 1), T(3, 1), T(2, 1), T(1, 1)]);
+    result[] = c * intarr[];
+    assert(result[] == [T(6, 1), T(5, 1), T(4, 1), T(3, 1), T(2, 1), T(1, 1)]);
+
+    result[] = arr[];
+    result[1..3] = intarr[1..3] * c;
+    assert(result[] == [T(1, 1), T(5, 1), T(4, 1), T(4, 4), T(5, 5), T(6, 6)]);
+    result[1..3] = c * intarr[1..3];
+    assert(result[] == [T(1, 1), T(5, 1), T(4, 1), T(4, 4), T(5, 5), T(6, 6)]);
+
+    result[1..$] = intarr[1..$] * c;
+    assert(result[] == [T(1, 1), T(5, 1), T(4, 1), T(3, 1), T(2, 1), T(1, 1)]);
+    result[1..$] = c * intarr[1..$];
+    assert(result[] == [T(1, 1), T(5, 1), T(4, 1), T(3, 1), T(2, 1), T(1, 1)]);
+
+    result[] = arr[];
+    result[1..3] = intarr[1..3] * arr[1..3];
+    assert(result[] == [T(1, 1), T(10, 2), T(12, 3), T(4, 4), T(5, 5), T(6, 6)]);
+    result[1..3] = arr[1..3] * intarr[1..3];
+    assert(result[] == [T(1, 1), T(10, 2), T(12, 3), T(4, 4), T(5, 5), T(6, 6)]);
+
+    result[] = [1,2,3,4,5,6] * c;
+    assert(result[] == [T(1, 1), T(2, 1), T(3, 1), T(4, 1), T(5, 1), T(6, 1)]);
+    result[] = c * [1,2,3,4,5,6];
+    assert(result[] == [T(1, 1), T(2, 1), T(3, 1), T(4, 1), T(5, 1), T(6, 1)]);
+
+    result[] = arr[] * [1,2,3,4,5,6];
+    assert(result[] == [T(1, 1), T(4, 2), T(9, 3), T(16, 4), T(25, 5), T(36, 6)]);
+    result[] = [1,2,3,4,5,6] *  arr[];
+    assert(result[] == [T(1, 1), T(4, 2), T(9, 3), T(16, 4), T(25, 5), T(36, 6)]);
+
+    result[] = [c, 2 * c, 3 * c, 4 * c, 5 * c, 6 * c] * [c, 2 * c, 3 * c, 4 * c, 5 * c, 6 * c];
+    assert(result[] == [T(1, 1), T(4, 1), T(9, 1), T(16, 1), T(25, 1), T(36, 1)]);
+
+    result[] = [c, 2 * c, 3 * c, 4 * c, 5 * c, 6 * c] * [1,2,3,4,5,6];
+    assert(result[] == [T(1, 1), T(4, 1), T(9, 1), T(16, 1), T(25, 1), T(36, 1)]);
+    result[] = [1,2,3,4,5,6] * [c, 2 * c, 3 * c, 4 * c, 5 * c, 6 * c];
+    assert(result[] == [T(1, 1), T(4, 1), T(9, 1), T(16, 1), T(25, 1), T(36, 1)]);
+
+    result[] = arr[] * c;
+    assert(result[] == [T(1, 1), T(2, 2), T(3, 3), T(4, 4), T(5, 5), T(6, 6)]);
+    result[] = c * arr[];
+    assert(result[] == [T(1, 1), T(2, 2), T(3, 3), T(4, 4), T(5, 5), T(6, 6)]);
+
+    result[] = c * 3.0f * arr[];
+    assert(result[] == [T(3, 1), T(6, 2), T(9, 3), T(12, 4), T(15, 5), T(18, 6)]);
+    result[] = 3.0f * c * arr[];
+    assert(result[] == [T(3, 1), T(6, 2), T(9, 3), T(12, 4), T(15, 5), T(18, 6)]);
+
+    result[] = arr[] * 3.0f * c;
+    assert(result[] == [T(3, 1), T(6, 2), T(9, 3), T(12, 4), T(15, 5), T(18, 6)]);
+    // result[] = arr[] * c * 3.0f; //not ok
+    // assert(result[] == [T(3, 1), T(6, 2), T(9, 3), T(12, 4), T(15, 5), T(18, 6)]);
+
+    result[] = 3.0f * arr[] * c;
+    assert(result[] == [T(3, 1), T(6, 2), T(9, 3), T(12, 4), T(15, 5), T(18, 6)]);
+    // result[] = c * arr[] * 3.0f; //not ok
+    // assert(result[] == [T(3, 1), T(6, 2), T(9, 3), T(12, 4), T(15, 5), T(18, 6)]);
+
+    result[] = c * arr[] * c;
+    assert(result[] == [T(1, 1), T(2, 2), T(3, 3), T(4, 4), T(5, 5), T(6, 6)]);
+}
diff --git a/gcc/testsuite/gdc.test/runnable/mars1.d b/gcc/testsuite/gdc.test/runnable/mars1.d
index 4f38f4d3322..30aa9503b09 100644
--- a/gcc/testsuite/gdc.test/runnable/mars1.d
+++ b/gcc/testsuite/gdc.test/runnable/mars1.d
@@ -1,5 +1,5 @@
 /*
-REQUIRED_ARGS: -mcpu=native -preview=intpromote
+REQUIRED_ARGS: -mcpu=native
 PERMUTE_ARGS: -O -inline -release
 */
 
diff --git a/gcc/testsuite/gdc.test/runnable/test15862.d b/gcc/testsuite/gdc.test/runnable/test15862.d
new file mode 100644
index 00000000000..87e25600d8b
--- /dev/null
+++ b/gcc/testsuite/gdc.test/runnable/test15862.d
@@ -0,0 +1,39 @@
+// https://issues.dlang.org/show_bug.cgi?id=15862
+
+/*
+PERMUTE_ARGS:
+REQUIRED_ARGS: -O -release
+*/
+
+
+int* p() pure nothrow {return new int;}
+int[] a() pure nothrow {return [0];}
+Object o() pure nothrow {return new Object;}
+
+auto pa() pure nothrow {return new int;}
+
+void main()
+{
+    {
+        int* p1 = p();
+        int* p2 = p();
+
+        if (p1 is p2) assert(0);
+
+        int[] a1 = a();
+        int[] a2 = a();
+
+        if (a1 is a2) assert(0);
+
+        Object o1 = o();
+        Object o2 = o();
+
+        if (o1 is o2) assert(0);
+    }
+    {
+        auto p1 = pa();
+        auto p2 = pa();
+
+        if (p1 is p2) assert(0);
+    }
+}
diff --git a/gcc/testsuite/gdc.test/runnable/test21367.d b/gcc/testsuite/gdc.test/runnable/test21367.d
new file mode 100644
index 00000000000..96e8d6c66d1
--- /dev/null
+++ b/gcc/testsuite/gdc.test/runnable/test21367.d
@@ -0,0 +1,47 @@
+// https://issues.dlang.org/show_bug.cgi?id=21367
+
+string result = "";
+
+struct RCArray(T)
+{
+    T* data;
+    this(this)
+    {
+        result ~= "A";
+    }
+    ~this()
+    {
+        result ~= "B";
+    }
+}
+
+struct Variant(T...)
+{
+    union
+    {
+        T payload;
+    }
+    this(this)
+    {
+        result ~= "C";
+    }
+
+    ~this()
+    {
+        result ~= "D";
+    }
+}
+
+alias Ft = Variant!(RCArray!double, RCArray!int);
+
+void fun(Ft a) {}
+void main()
+{
+    Ft a;
+    Ft b = a;
+}
+
+static ~this()
+{
+    assert(result == "CDD");
+}
diff --git a/gcc/testsuite/gdc.test/runnable/test22227.d b/gcc/testsuite/gdc.test/runnable/test22227.d
new file mode 100644
index 00000000000..7ef53c37a60
--- /dev/null
+++ b/gcc/testsuite/gdc.test/runnable/test22227.d
@@ -0,0 +1,16 @@
+// REQUIRED_ARGS: -debug -O -release
+// https://issues.dlang.org/show_bug.cgi?id=22277
+
+bool secret = false;
+
+void free(immutable void* x) pure nothrow
+{
+    debug secret = true;
+}
+
+void main()
+{
+    free(null);
+    if (!secret)
+        assert(0);
+}
diff --git a/gcc/testsuite/gdc.test/runnable/testOpApply.d b/gcc/testsuite/gdc.test/runnable/testOpApply.d
index 7b884e5857c..285365eea82 100644
--- a/gcc/testsuite/gdc.test/runnable/testOpApply.d
+++ b/gcc/testsuite/gdc.test/runnable/testOpApply.d
@@ -1,4 +1,4 @@
-/* PERMUTE_ARGS:
+/* PERMUTE_ARGS: -preview=dip1000
  */
 
 // https://issues.dlang.org/show_bug.cgi?id=15624
@@ -140,3 +140,32 @@ void testInverseAttributes()
     }
     safe();
 }
+
+// https://issues.dlang.org/show_bug.cgi?id=20907
+Lockstep!() lockstep()
+{
+    return Lockstep!()();
+}
+
+struct Lockstep()
+{
+    int opApply(int delegate(int) callback) @system
+    {
+        return 0;
+    }
+
+    int opApply(int delegate(int) pure nothrow @nogc @safe callback) pure nothrow @nogc @safe
+    {
+        return 0;
+    }
+}
+
+void foo0()
+{
+    foreach (x; lockstep()) {}
+}
+
+void foo1()
+{
+    foreach (x; lockstep()) {}
+}
diff --git a/gcc/testsuite/gdc.test/runnable/testcgelem.d b/gcc/testsuite/gdc.test/runnable/testcgelem.d
index b5c7f7d1855..617e3fb11cc 100644
--- a/gcc/testsuite/gdc.test/runnable/testcgelem.d
+++ b/gcc/testsuite/gdc.test/runnable/testcgelem.d
@@ -1,5 +1,5 @@
 /*
-REQUIRED_ARGS: -mcpu=native -preview=intpromote
+REQUIRED_ARGS: -mcpu=native
 PERMUTE_ARGS: -O -inline -release
 */
 
diff --git a/gcc/testsuite/gdc.test/runnable/testconst.d b/gcc/testsuite/gdc.test/runnable/testconst.d
index 5c0e75de60f..764bb1b045e 100644
--- a/gcc/testsuite/gdc.test/runnable/testconst.d
+++ b/gcc/testsuite/gdc.test/runnable/testconst.d
@@ -2860,9 +2860,11 @@ static assert(is(S7038b == shared));
 immutable struct S7038c{ int x; }
 static assert(is(S7038c == immutable));
 
-static assert(!is(C7038 == const));
+// https://issues.dlang.org/show_bug.cgi?id=22515
+// Classes fixed for consistency with structs
+static assert(is(C7038 == const));
 const class C7038{ int x; }
-static assert(!is(C7038 == const));
+static assert(is(C7038 == const));
 
 void test7038()
 {
@@ -2871,7 +2873,7 @@ void test7038()
     static assert(is(typeof(s.x) == const int));
 
     C7038 c;
-    static assert(!is(typeof(c) == const));
+    static assert(is(typeof(c) == const));
     static assert(is(typeof(c.x) == const int));
 }
 
diff --git a/gcc/testsuite/gdc.test/runnable/traits_initSymbol.d b/gcc/testsuite/gdc.test/runnable/traits_initSymbol.d
new file mode 100644
index 00000000000..0385d98c8ff
--- /dev/null
+++ b/gcc/testsuite/gdc.test/runnable/traits_initSymbol.d
@@ -0,0 +1,119 @@
+struct Zero
+{
+    int x;
+}
+
+void testZero()
+{
+    auto zeroInit = __traits(initSymbol, Zero);
+    static assert(is(typeof(zeroInit) == const(void[])));
+
+    assert(zeroInit.ptr is null);
+    assert(zeroInit.length == Zero.sizeof);
+}
+
+struct NonZero
+{
+    long x = 1;
+}
+
+void testNonZero()
+{
+    auto nonZeroInit = __traits(initSymbol, NonZero);
+    static assert(is(typeof(nonZeroInit) == const(void[])));
+
+    assert(nonZeroInit.ptr);
+    assert(nonZeroInit.length == NonZero.sizeof);
+    assert(cast(const(long[])) nonZeroInit == [1L]);
+}
+
+class C
+{
+    short x = 123;
+}
+
+void testClass()
+{
+    auto cInit = __traits(initSymbol, C);
+    static assert(is(typeof(cInit) == const(void[])));
+
+    assert(cInit.ptr);
+    assert(cInit.length == __traits(classInstanceSize, C));
+
+    scope c = new C;
+    assert((cast(void*) c)[0 .. cInit.length] == cInit);
+}
+
+struct AlignedStruct
+{
+    short s = 5;
+    // 2 byte padding
+    align(4) char c = 'c';
+    // 3 byte padding
+    int i = 4;
+    // reduced alignment
+    align(1) long l = 0xDEADBEEF;
+}
+
+void testAlignedStruct()
+{
+    auto init = __traits(initSymbol, AlignedStruct);
+
+    assert(init.ptr);
+    assert(init.length == AlignedStruct.sizeof);
+
+    version (GNU)
+        AlignedStruct exp = AlignedStruct();
+    else
+        AlignedStruct exp;
+    assert(init == (cast(void*) &exp)[0 .. AlignedStruct.sizeof]);
+
+}
+
+class AlignedClass : C
+{
+    short s = 5;
+    // 2 byte padding
+    align(4) char c = 'c';
+    // 3 byte padding
+    int i = 4;
+    // reduced alignment
+    align(1) long l = 0xDEADBEEF;
+}
+
+void testAlignedClass()
+{
+    auto init = __traits(initSymbol, AlignedClass);
+
+    assert(init.ptr);
+    assert(init.length == __traits(classInstanceSize, AlignedClass));
+
+    scope ac = new AlignedClass();
+    assert(init == (cast(void*) ac)[0 .. init.length]);
+}
+
+extern (C++) class ExternCppClass
+{
+    int i = 4;
+}
+
+void testExternCppClass()
+{
+    auto init = __traits(initSymbol, ExternCppClass);
+
+    assert(init.ptr);
+    assert(init.length == __traits(classInstanceSize, ExternCppClass));
+
+    scope ac = new ExternCppClass();
+    assert(init == (cast(void*) ac)[0 .. init.length]);
+}
+
+void main()
+{
+    testZero();
+    testNonZero();
+    testClass();
+    testAlignedStruct();
+    testAlignedClass();
+    testExternCppClass();
+}
diff --git a/gcc/testsuite/gdc.test/runnable/xtest46.d b/gcc/testsuite/gdc.test/runnable/xtest46.d
index 20cc225759a..4fe6b00eba7 100644
--- a/gcc/testsuite/gdc.test/runnable/xtest46.d
+++ b/gcc/testsuite/gdc.test/runnable/xtest46.d
@@ -4903,7 +4903,7 @@ static assert(is(typeof(S5933d.x) == FuncType5933));
 
 
 class C5933a { auto x() { return 0; } }
-static assert(is(typeof(&(new C5933b()).x) == int delegate()));
+static assert(is(typeof(&(new C5933b()).x) == int delegate() pure nothrow @nogc @safe));
 
 class C5933b { auto x() { return 0; } }
 //static assert(is(typeof((new C5933b()).x) == FuncType5933));
@@ -7923,8 +7923,9 @@ void test17349()
 {
     static struct S
     {
-        int bar(void delegate(ref int*)) { return 1; }
-        int bar(void delegate(ref const int*)) const { return 2; }
+        // Specify attribute inferred for dg1/dg2
+        int bar(void delegate(ref int*) pure nothrow @nogc @safe) { return 1; }
+        int bar(void delegate(ref const int*) pure nothrow @nogc @safe) const { return 2; }
     }
 
     void dg1(ref int*) { }
diff --git a/gcc/testsuite/gdc.test/runnable_cxx/extra-files/cpp7925.cpp b/gcc/testsuite/gdc.test/runnable_cxx/extra-files/cpp7925.cpp
new file mode 100644
index 00000000000..f3a9a8552a9
--- /dev/null
+++ b/gcc/testsuite/gdc.test/runnable_cxx/extra-files/cpp7925.cpp
@@ -0,0 +1,103 @@
+#include <stdarg.h>
+#include <assert.h>
+
+class C1
+{
+public:
+    virtual ~C1();
+
+    int i;
+
+    int f0();
+    int f1(int a);
+    int f2(int a, int b);
+    virtual int f3(int a, int b);
+    int f4(int a, ...);
+};
+
+C1::~C1()
+{
+}
+
+int C1::f0()
+{
+    return i;
+}
+
+int C1::f1(int a)
+{
+    return i + a;
+}
+
+int C1::f2(int a, int b)
+{
+    return i + a + b;
+}
+
+int C1::f3(int a, int b)
+{
+    return i + a + b;
+}
+
+int C1::f4(int a, ...)
+{
+    int r = i + a;
+    int last = a;
+
+    va_list argp;
+    va_start(argp, a);
+    while (last)
+    {
+        last = va_arg(argp, int);
+        r += last;
+    }
+    va_end(argp);
+    return r;
+}
+
+C1 *createC1()
+{
+    return new C1();
+}
+
+class C2
+{
+public:
+    virtual ~C2();
+
+    int i;
+
+    int f0();
+    int f1(int a);
+    int f2(int a, int b);
+    virtual int f3(int a, int b);
+    int f4(int a, ...);
+};
+
+C2 *createC2();
+
+void runCPPTests()
+{
+    C2 *c2 = createC2();
+    c2->i = 100;
+    assert(c2->f0() == 100);
+    assert(c2->f1(1) == 101);
+    assert(c2->f2(20, 3) == 123);
+    assert(c2->f3(20, 3) == 123);
+    assert(c2->f4(20, 3, 0) == 123);
+
+    int (C2::*fp0)() = &C2::f0;
+    int (C2::*fp1)(int) = &C2::f1;
+    int (C2::*fp2)(int, int) = &C2::f2;
+    int (C2::*fp3)(int, int) = &C2::f3;
+#ifndef __DMC__
+    int (C2::*fp4)(int, ...) = &C2::f4;
+#endif
+    assert((c2->*(fp0))() == 100);
+    assert((c2->*(fp1))(1) == 101);
+    assert((c2->*(fp2))(20, 3) == 123);
+    assert((c2->*(fp3))(20, 3) == 123);
+#ifndef __DMC__
+    assert((c2->*(fp4))(20, 3, 0) == 123);
+#endif
+}
diff --git a/gcc/testsuite/gdc.test/runnable_cxx/test7925.d b/gcc/testsuite/gdc.test/runnable_cxx/test7925.d
new file mode 100644
index 00000000000..2f52826bc4f
--- /dev/null
+++ b/gcc/testsuite/gdc.test/runnable_cxx/test7925.d
@@ -0,0 +1,151 @@
+// EXTRA_CPP_SOURCES: cpp7925.cpp
+
+/*
+Exclude -O due to a codegen bug on OSX:
+https://issues.dlang.org/show_bug.cgi?id=22556
+
+PERMUTE_ARGS(osx): -inline -release -g
+*/
+
+import core.vararg;
+
+extern(C++) class C1
+{
+public:
+    ~this();
+
+    int i;
+
+    final int f0();
+    final int f1(int a);
+    final int f2(int a, int b);
+    int f3(int a, int b);
+    final int f4(int a, ...);
+};
+
+extern(C++) C1 createC1();
+
+extern(C++) class C2
+{
+public:
+    ~this()
+    {
+    }
+
+    int i;
+
+    final int f0()
+    {
+        return i;
+    }
+
+    final int f1(int a)
+    {
+        return i + a;
+    }
+
+    final int f2(int a, int b)
+    {
+        return i + a + b;
+    }
+
+    int f3(int a, int b)
+    {
+        return i + a + b;
+    }
+
+    final int f4(int a, ...)
+    {
+        int r = i + a;
+        int last = a;
+
+        va_list argp;
+        va_start(argp, a);
+        while (last)
+        {
+            last = va_arg!int(argp);
+            r += last;
+        }
+        va_end(argp);
+        return r;
+    }
+};
+
+extern(C++) C2 createC2()
+{
+    return new C2;
+}
+
+auto callMember(alias F, Params...)(__traits(parent, F) obj, Params params)
+{
+    static if(__traits(getFunctionVariadicStyle, F) == "stdarg")
+        enum varargSuffix = ", ...";
+    else
+        enum varargSuffix = "";
+
+    static if(is(typeof(&F) R == return) && is(typeof(F) P == __parameters))
+        mixin("extern(" ~ __traits(getLinkage, F) ~ ") R delegate(P" ~ varargSuffix ~ ") dg;");
+    dg.funcptr = &F;
+    dg.ptr = cast(void*)obj;
+    return dg(params);
+}
+
+extern(C++) void runCPPTests();
+
+void main()
+{
+    C1 c1 = createC1();
+    c1.i = 100;
+    assert(c1.f0() == 100);
+    assert(c1.f1(1) == 101);
+    assert(c1.f2(20, 3) == 123);
+    assert(c1.f3(20, 3) == 123);
+    assert(c1.f4(20, 3, 0) == 123);
+
+    auto dg0 = &c1.f0;
+    auto dg1 = &c1.f1;
+    auto dg2 = &c1.f2;
+    auto dg3 = &c1.f3;
+    auto dg4 = &c1.f4;
+    assert(dg0() == 100);
+    assert(dg1(1) == 101);
+    assert(dg2(20, 3) == 123);
+    assert(dg3(20, 3) == 123);
+    assert(dg4(20, 3, 0) == 123);
+
+    assert(callMember!(C1.f0)(c1) == 100);
+    assert(callMember!(C1.f1)(c1, 1) == 101);
+    assert(callMember!(C1.f2)(c1, 20, 3) == 123);
+    assert(callMember!(C1.f3)(c1, 20, 3) == 123);
+    assert(callMember!(C1.f4)(c1, 20, 3, 0) == 123);
+
+    int i;
+    extern(C++) void delegate() lamdba1 = () {
+        i = 5;
+    };
+    lamdba1();
+    assert(i == 5);
+
+    extern(C++) int function(int, int) lamdba2 = (int a, int b) {
+        return a + b;
+    };
+    assert(lamdba2(3, 4) == 7);
+
+    extern(C++) void delegate(int, ...) lamdba3 = (int a, ...) {
+        i = a;
+        int last = a;
+
+        va_list argp;
+        va_start(argp, a);
+        while (last)
+        {
+            last = va_arg!int(argp);
+            i += last;
+        }
+        va_end(argp);
+    };
+    lamdba3(1000, 200, 30, 4, 0);
+    assert(i == 1234);
+
+    runCPPTests();
+}
diff --git a/libphobos/libdruntime/MERGE b/libphobos/libdruntime/MERGE
index d0d3a25ad1e..edb101758b8 100644
--- a/libphobos/libdruntime/MERGE
+++ b/libphobos/libdruntime/MERGE
@@ -1,4 +1,4 @@
-178c44ff362902af589603767055cfac89215652
+bc58b1e9ea68051af9094651a26313371297b79f
 
 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/Makefile.am b/libphobos/libdruntime/Makefile.am
index 44d4fe16be0..224d06e78ca 100644
--- a/libphobos/libdruntime/Makefile.am
+++ b/libphobos/libdruntime/Makefile.am
@@ -280,9 +280,8 @@ DRUNTIME_DSOURCES_LINUX = core/sys/linux/config.d \
 	core/sys/linux/sys/procfs.d core/sys/linux/sys/signalfd.d \
 	core/sys/linux/sys/socket.d core/sys/linux/sys/sysinfo.d \
 	core/sys/linux/sys/time.d core/sys/linux/sys/xattr.d \
-	core/sys/linux/syscalls.d core/sys/linux/termios.d \
-	core/sys/linux/time.d core/sys/linux/timerfd.d core/sys/linux/tipc.d \
-	core/sys/linux/unistd.d
+	core/sys/linux/termios.d core/sys/linux/time.d \
+	core/sys/linux/timerfd.d core/sys/linux/tipc.d core/sys/linux/unistd.d
 
 DRUNTIME_DSOURCES_NETBSD = core/sys/netbsd/dlfcn.d \
 	core/sys/netbsd/err.d core/sys/netbsd/execinfo.d \
diff --git a/libphobos/libdruntime/Makefile.in b/libphobos/libdruntime/Makefile.in
index 84be8082f7a..bb936ddc1ff 100644
--- a/libphobos/libdruntime/Makefile.in
+++ b/libphobos/libdruntime/Makefile.in
@@ -367,9 +367,9 @@ am__objects_18 = core/sys/linux/config.lo core/sys/linux/dlfcn.lo \
 	core/sys/linux/sys/procfs.lo core/sys/linux/sys/signalfd.lo \
 	core/sys/linux/sys/socket.lo core/sys/linux/sys/sysinfo.lo \
 	core/sys/linux/sys/time.lo core/sys/linux/sys/xattr.lo \
-	core/sys/linux/syscalls.lo core/sys/linux/termios.lo \
-	core/sys/linux/time.lo core/sys/linux/timerfd.lo \
-	core/sys/linux/tipc.lo core/sys/linux/unistd.lo
+	core/sys/linux/termios.lo core/sys/linux/time.lo \
+	core/sys/linux/timerfd.lo core/sys/linux/tipc.lo \
+	core/sys/linux/unistd.lo
 @DRUNTIME_OS_LINUX_TRUE@am__objects_19 = $(am__objects_18)
 am__objects_20 = core/sys/windows/accctrl.lo \
 	core/sys/windows/aclapi.lo core/sys/windows/aclui.lo \
@@ -944,9 +944,8 @@ DRUNTIME_DSOURCES_LINUX = core/sys/linux/config.d \
 	core/sys/linux/sys/procfs.d core/sys/linux/sys/signalfd.d \
 	core/sys/linux/sys/socket.d core/sys/linux/sys/sysinfo.d \
 	core/sys/linux/sys/time.d core/sys/linux/sys/xattr.d \
-	core/sys/linux/syscalls.d core/sys/linux/termios.d \
-	core/sys/linux/time.d core/sys/linux/timerfd.d core/sys/linux/tipc.d \
-	core/sys/linux/unistd.d
+	core/sys/linux/termios.d core/sys/linux/time.d \
+	core/sys/linux/timerfd.d core/sys/linux/tipc.d core/sys/linux/unistd.d
 
 DRUNTIME_DSOURCES_NETBSD = core/sys/netbsd/dlfcn.d \
 	core/sys/netbsd/err.d core/sys/netbsd/execinfo.d \
@@ -1675,7 +1674,6 @@ core/sys/linux/sys/socket.lo: core/sys/linux/sys/$(am__dirstamp)
 core/sys/linux/sys/sysinfo.lo: core/sys/linux/sys/$(am__dirstamp)
 core/sys/linux/sys/time.lo: core/sys/linux/sys/$(am__dirstamp)
 core/sys/linux/sys/xattr.lo: core/sys/linux/sys/$(am__dirstamp)
-core/sys/linux/syscalls.lo: core/sys/linux/$(am__dirstamp)
 core/sys/linux/termios.lo: core/sys/linux/$(am__dirstamp)
 core/sys/linux/time.lo: core/sys/linux/$(am__dirstamp)
 core/sys/linux/timerfd.lo: core/sys/linux/$(am__dirstamp)
diff --git a/libphobos/libdruntime/core/demangle.d b/libphobos/libdruntime/core/demangle.d
index 33ca0ddc7bd..1915fb0844a 100644
--- a/libphobos/libdruntime/core/demangle.d
+++ b/libphobos/libdruntime/core/demangle.d
@@ -54,13 +54,13 @@ pure @safe:
     enum AddType { no, yes }
 
 
-    this( return const(char)[] buf_, return char[] dst_ = null )
+    this( return scope const(char)[] buf_, return scope char[] dst_ = null )
     {
         this( buf_, AddType.yes, dst_ );
     }
 
 
-    this( return const(char)[] buf_, AddType addType_, return char[] dst_ = null )
+    this( return scope const(char)[] buf_, AddType addType_, return scope char[] dst_ = null )
     {
         buf     = buf_;
         addType = addType_;
@@ -105,7 +105,7 @@ pure @safe:
         //throw new ParseException( msg );
         debug(info) printf( "error: %.*s\n", cast(int) msg.length, msg.ptr );
         throw __ctfe ? new ParseException(msg)
-                     : cast(ParseException) cast(void*) typeid(ParseException).initializer;
+                     : cast(ParseException) __traits(initSymbol, ParseException).ptr;
 
     }
 
@@ -116,7 +116,7 @@ pure @safe:
 
         //throw new OverflowException( msg );
         debug(info) printf( "overflow: %.*s\n", cast(int) msg.length, msg.ptr );
-        throw cast(OverflowException) cast(void*) typeid(OverflowException).initializer;
+        throw cast(OverflowException) __traits(initSymbol, OverflowException).ptr;
     }
 
 
diff --git a/libphobos/libdruntime/core/internal/array/construction.d b/libphobos/libdruntime/core/internal/array/construction.d
index 9c8223767e1..ae71f513129 100644
--- a/libphobos/libdruntime/core/internal/array/construction.d
+++ b/libphobos/libdruntime/core/internal/array/construction.d
@@ -14,16 +14,27 @@ import core.internal.traits : Unqual;
 /**
  * Does array initialization (not assignment) from another array of the same element type.
  * Params:
+ *  to = what array to initialize
  *  from = what data the array should be initialized with
+ *  makeWeaklyPure = unused; its purpose is to prevent the function from becoming
+ *      strongly pure and risk being optimised out
  * Returns:
  *  The created and initialized array `to`
  * Bugs:
  *  This function template was ported from a much older runtime hook that bypassed safety,
  *  purity, and throwabilty checks. To prevent breaking existing code, this function template
  *  is temporarily declared `@trusted` until the implementation can be brought up to modern D expectations.
+ *
+ *  The third parameter is never used, but is necessary in order for the
+ *  function be treated as weakly pure, instead of strongly pure.
+ *  This is needed because constructions such as the one below can be ignored by
+ *  the compiler if `_d_arrayctor` is believed to be pure, because purity would
+ *  mean the call to `_d_arrayctor` has no effects (no side effects and the
+ *  return value is ignored), despite it actually modifying the contents of `a`.
+ *      const S[2] b;
+ *      const S[2] a = b;  // this would get lowered to _d_arrayctor(a, b)
  */
-Tarr1 _d_arrayctor(Tarr1 : T1[], Tarr2 : T2[], T1, T2)(scope Tarr2 from) @trusted
-    if (is(Unqual!T1 == Unqual!T2))
+Tarr _d_arrayctor(Tarr : T[], T)(return scope Tarr to, scope Tarr from, char* makeWeaklyPure = null) @trusted
 {
     pragma(inline, false);
     import core.internal.traits : hasElaborateCopyConstructor;
@@ -32,14 +43,12 @@ Tarr1 _d_arrayctor(Tarr1 : T1[], Tarr2 : T2[], T1, T2)(scope Tarr2 from) @truste
     import core.stdc.stdint : uintptr_t;
     debug(PRINTF) import core.stdc.stdio : printf;
 
-    debug(PRINTF) printf("_d_arrayctor(to = %p,%d, from = %p,%d) size = %d\n", from.ptr, from.length, to.ptr, to.length, T1.tsize);
+    debug(PRINTF) printf("_d_arrayctor(from = %p,%d) size = %d\n", from.ptr, from.length, T.sizeof);
 
-    Tarr1 to = void;
+    void[] vFrom = (cast(void*) from.ptr)[0..from.length];
+    void[] vTo = (cast(void*) to.ptr)[0..to.length];
 
-    void[] vFrom = (cast(void*)from.ptr)[0..from.length];
-    void[] vTo = (cast(void*)to.ptr)[0..to.length];
-
-    // Force `enforceRawArraysConformable` to be `pure`
+    // Force `enforceRawArraysConformable` to remain weakly `pure`
     void enforceRawArraysConformable(const char[] action, const size_t elementSize,
         const void[] a1, const void[] a2) @trusted
     {
@@ -50,9 +59,9 @@ Tarr1 _d_arrayctor(Tarr1 : T1[], Tarr2 : T2[], T1, T2)(scope Tarr2 from) @truste
         (cast(Type)&enforceRawArraysConformableNogc)(action, elementSize, a1, a2, false);
     }
 
-    enforceRawArraysConformable("initialization", T1.sizeof, vFrom, vTo);
+    enforceRawArraysConformable("initialization", T.sizeof, vFrom, vTo);
 
-    static if (hasElaborateCopyConstructor!T1)
+    static if (hasElaborateCopyConstructor!T)
     {
         size_t i;
         try
@@ -66,7 +75,7 @@ Tarr1 _d_arrayctor(Tarr1 : T1[], Tarr2 : T2[], T1, T2)(scope Tarr2 from) @truste
             */
             while (i--)
             {
-                auto elem = cast(Unqual!T1*)&to[i];
+                auto elem = cast(Unqual!T*) &to[i];
                 destroy(*elem);
             }
 
@@ -76,7 +85,7 @@ Tarr1 _d_arrayctor(Tarr1 : T1[], Tarr2 : T2[], T1, T2)(scope Tarr2 from) @truste
     else
     {
         // blit all elements at once
-        memcpy(cast(void*) to.ptr, from.ptr, to.length * T1.sizeof);
+        memcpy(cast(void*) to.ptr, from.ptr, to.length * T.sizeof);
     }
 
     return to;
@@ -94,7 +103,7 @@ Tarr1 _d_arrayctor(Tarr1 : T1[], Tarr2 : T2[], T1, T2)(scope Tarr2 from) @truste
 
     S[4] arr1;
     S[4] arr2 = [S(0), S(1), S(2), S(3)];
-    arr1 = _d_arrayctor!(typeof(arr1))(arr2[]);
+    _d_arrayctor(arr1[], arr2[]);
 
     assert(counter == 4);
     assert(arr1 == arr2);
@@ -117,7 +126,7 @@ Tarr1 _d_arrayctor(Tarr1 : T1[], Tarr2 : T2[], T1, T2)(scope Tarr2 from) @truste
 
     S[4] arr1;
     S[4] arr2 = [S(0), S(1), S(2), S(3)];
-    arr1 = _d_arrayctor!(typeof(arr1))(arr2[]);
+    _d_arrayctor(arr1[], arr2[]);
 
     assert(counter == 4);
     assert(arr1 == arr2);
@@ -143,7 +152,7 @@ Tarr1 _d_arrayctor(Tarr1 : T1[], Tarr2 : T2[], T1, T2)(scope Tarr2 from) @truste
     {
         Throw[4] a;
         Throw[4] b = [Throw(1), Throw(2), Throw(3), Throw(4)];
-        a = _d_arrayctor!(typeof(a))(b[]);
+        _d_arrayctor(a[], b[]);
     }
     catch (Exception)
     {
@@ -168,7 +177,7 @@ Tarr1 _d_arrayctor(Tarr1 : T1[], Tarr2 : T2[], T1, T2)(scope Tarr2 from) @truste
     {
         NoThrow[4] a;
         NoThrow[4] b = [NoThrow(1), NoThrow(2), NoThrow(3), NoThrow(4)];
-        a = _d_arrayctor!(typeof(a))(b[]);
+        _d_arrayctor(a[], b[]);
     }
     catch (Exception)
     {
@@ -274,7 +283,7 @@ void _d_arraysetctor(Tarr : T[], T)(scope Tarr p, scope ref T value) @trusted
     {
         Throw[4] a;
         Throw[4] b = [Throw(1), Throw(2), Throw(3), Throw(4)];
-        a = _d_arrayctor!(typeof(a))(b[]);
+        _d_arrayctor(a[], b[]);
     }
     catch (Exception)
     {
diff --git a/libphobos/libdruntime/core/internal/convert.d b/libphobos/libdruntime/core/internal/convert.d
index 2789d2913a7..a876fcc537f 100644
--- a/libphobos/libdruntime/core/internal/convert.d
+++ b/libphobos/libdruntime/core/internal/convert.d
@@ -801,7 +801,7 @@ const(ubyte)[] toUbyte(T)(const ref T val) if (is(T == delegate) || is(T : V*, V
 }
 
 @trusted pure nothrow @nogc
-const(ubyte)[] toUbyte(T)(const ref return scope T val) if (is(T == struct) || is(T == union))
+const(ubyte)[] toUbyte(T)(const return ref scope T val) if (is(T == struct) || is(T == union))
 {
     if (__ctfe)
     {
@@ -826,7 +826,11 @@ const(ubyte)[] toUbyte(T)(const ref return scope T val) if (is(T == struct) || i
     }
     else
     {
-        return (cast(const(ubyte)*)&val)[0 .. T.sizeof];
+        // We're escaping a reference to `val` here because we cannot express
+        // ref return + scope, it's currently seen as ref + return scope
+        // https://issues.dlang.org/show_bug.cgi?id=22541
+        // Once fixed, the @system lambda should be removed
+        return (() @system => (cast(const(ubyte)*)&val)[0 .. T.sizeof])();
     }
 }
 
diff --git a/libphobos/libdruntime/core/internal/lifetime.d b/libphobos/libdruntime/core/internal/lifetime.d
index 7e9b5f2ad48..a7446debae6 100644
--- a/libphobos/libdruntime/core/internal/lifetime.d
+++ b/libphobos/libdruntime/core/internal/lifetime.d
@@ -89,44 +89,35 @@ Emplaces T.init.
 In contrast to `emplaceRef(chunk)`, there are no checks for disabled default
 constructors etc.
 +/
-template emplaceInitializer(T)
+void emplaceInitializer(T)(scope ref T chunk) nothrow pure @trusted
 if (!is(T == const) && !is(T == immutable) && !is(T == inout))
 {
-    import core.internal.traits : hasElaborateAssign, Unqual;
+    import core.internal.traits : hasElaborateAssign;
 
-    // Avoid stack allocation by hacking to get to the struct/union init symbol.
-    static if (is(T == struct) || is(T == union))
+    static if (__traits(isZeroInit, T))
     {
-        pragma(mangle, "_D" ~ Unqual!T.mangleof[1..$] ~ "6__initZ")
-        __gshared extern immutable T initializer;
+        import core.stdc.string : memset;
+        memset(cast(void*) &chunk, 0, T.sizeof);
     }
-
-    void emplaceInitializer(scope ref T chunk) nothrow pure @trusted
+    else static if (__traits(isScalar, T) ||
+                    T.sizeof <= 16 && !hasElaborateAssign!T && __traits(compiles, (){ T chunk; chunk = T.init; }))
     {
-        static if (__traits(isZeroInit, T))
-        {
-            import core.stdc.string : memset;
-            memset(cast(void*) &chunk, 0, T.sizeof);
-        }
-        else static if (__traits(isScalar, T) ||
-                        T.sizeof <= 16 && !hasElaborateAssign!T && __traits(compiles, (){ T chunk; chunk = T.init; }))
-        {
-            chunk = T.init;
-        }
-        else static if (__traits(isStaticArray, T))
-        {
-            // For static arrays there is no initializer symbol created. Instead, we emplace elements one-by-one.
-            foreach (i; 0 .. T.length)
-            {
-                emplaceInitializer(chunk[i]);
-            }
-        }
-        else
+        chunk = T.init;
+    }
+    else static if (__traits(isStaticArray, T))
+    {
+        // For static arrays there is no initializer symbol created. Instead, we emplace elements one-by-one.
+        foreach (i; 0 .. T.length)
         {
-            import core.stdc.string : memcpy;
-            memcpy(cast(void*)&chunk, &initializer, T.sizeof);
+            emplaceInitializer(chunk[i]);
         }
     }
+    else
+    {
+        import core.stdc.string : memcpy;
+        const initializer = __traits(initSymbol, T);
+        memcpy(cast(void*)&chunk, initializer.ptr, initializer.length);
+    }
 }
 
 @safe unittest
diff --git a/libphobos/libdruntime/core/internal/string.d b/libphobos/libdruntime/core/internal/string.d
index 529fee49436..64a9cc92ffb 100644
--- a/libphobos/libdruntime/core/internal/string.d
+++ b/libphobos/libdruntime/core/internal/string.d
@@ -119,7 +119,7 @@ char[] signedToTempString(uint radix = 10)(long value, return scope char[] buf)
     if (neg)
     {
         // about to do a slice without a bounds check
-        auto trustedSlice(return char[] r) @trusted { assert(r.ptr > buf.ptr); return (r.ptr-1)[0..r.length+1]; }
+        auto trustedSlice(return scope char[] r) @trusted { assert(r.ptr > buf.ptr); return (r.ptr-1)[0..r.length+1]; }
         r = trustedSlice(r);
         r[0] = '-';
     }
diff --git a/libphobos/libdruntime/core/internal/utf.d b/libphobos/libdruntime/core/internal/utf.d
index ca0f7f599a6..27bf7f2b905 100644
--- a/libphobos/libdruntime/core/internal/utf.d
+++ b/libphobos/libdruntime/core/internal/utf.d
@@ -583,7 +583,7 @@ void validate(S)(const scope S s)
 /* =================== Conversion to UTF8 ======================= */
 
 @safe pure nothrow @nogc
-char[] toUTF8(return char[] buf, dchar c)
+char[] toUTF8(return scope char[] buf, dchar c)
     in
     {
         assert(isValidDchar(c));
@@ -623,7 +623,7 @@ char[] toUTF8(return char[] buf, dchar c)
  * Encodes string s into UTF-8 and returns the encoded string.
  */
 @safe pure nothrow
-string toUTF8(return string s)
+string toUTF8(return scope string s)
     in
     {
         validate(s);
@@ -692,7 +692,7 @@ string toUTF8(const scope dchar[] s)
 /* =================== Conversion to UTF16 ======================= */
 
 @safe pure nothrow @nogc
-wchar[] toUTF16(return wchar[] buf, dchar c)
+wchar[] toUTF16(return scope wchar[] buf, dchar c)
     in
     {
         assert(isValidDchar(c));
@@ -784,7 +784,7 @@ wptr toUTF16z(const scope char[] s)
 
 /** ditto */
 @safe pure nothrow
-wstring toUTF16(return wstring s)
+wstring toUTF16(return scope wstring s)
     in
     {
         validate(s);
@@ -864,7 +864,7 @@ dstring toUTF32(const scope wchar[] s)
 
 /** ditto */
 @safe pure nothrow
-dstring toUTF32(return dstring s)
+dstring toUTF32(return scope dstring s)
     in
     {
         validate(s);
diff --git a/libphobos/libdruntime/core/lifetime.d b/libphobos/libdruntime/core/lifetime.d
index d93b891226c..b45e95f4226 100644
--- a/libphobos/libdruntime/core/lifetime.d
+++ b/libphobos/libdruntime/core/lifetime.d
@@ -103,8 +103,8 @@ T emplace(T, Args...)(T chunk, auto ref Args args)
         " is abstract and it can't be emplaced");
 
     // Initialize the object in its pre-ctor state
-    enum classSize = __traits(classInstanceSize, T);
-    (() @trusted => (cast(void*) chunk)[0 .. classSize] = typeid(T).initializer[])();
+    const initializer = __traits(initSymbol, T);
+    (() @trusted { (cast(void*) chunk)[0 .. initializer.length] = initializer[]; })();
 
     static if (isInnerClass!T)
     {
@@ -224,6 +224,31 @@ T emplace(T, Args...)(void[] chunk, auto ref Args args)
     assert(c.i == 5);
 }
 
+///
+@betterC
+@nogc pure nothrow @system unittest
+{
+    // works with -betterC too:
+
+    static extern (C++) class C
+    {
+        @nogc pure nothrow @safe:
+        int i = 3;
+        this(int i)
+        {
+            assert(this.i == 3);
+            this.i = i;
+        }
+        int virtualGetI() { return i; }
+    }
+
+    import core.internal.traits : classInstanceAlignment;
+
+    align(classInstanceAlignment!C) byte[__traits(classInstanceSize, C)] buffer;
+    C c = emplace!C(buffer[], 42);
+    assert(c.virtualGetI() == 42);
+}
+
 @system unittest
 {
     class Outer
@@ -1921,7 +1946,7 @@ private void moveImpl(T)(scope ref T target, return scope ref T source)
 
     static if (is(T == struct))
     {
-        //  Unsafe when compiling without -dip1000
+        //  Unsafe when compiling without -preview=dip1000
         if ((() @trusted => &source == &target)()) return;
         // Destroy target before overwriting it
         static if (hasElaborateDestructor!T) target.__xdtor();
@@ -2099,7 +2124,7 @@ private void moveEmplaceImpl(T)(scope ref T target, return scope ref T source)
 
     static if (is(T == struct))
     {
-        //  Unsafe when compiling without -dip1000
+        //  Unsafe when compiling without -preview=dip1000
         assert((() @trusted => &source !is &target)(), "source and target must not be identical");
 
         static if (hasElaborateAssign!T || !isAssignable!T)
@@ -2123,12 +2148,7 @@ private void moveEmplaceImpl(T)(scope ref T target, return scope ref T source)
             static if (__traits(isZeroInit, T))
                 () @trusted { memset(&source, 0, sz); }();
             else
-            {
-                import core.internal.lifetime : emplaceInitializer;
-                ubyte[T.sizeof] init = void;
-                emplaceInitializer(*(() @trusted { return cast(T*)init.ptr; }()));
-                () @trusted { memcpy(&source, init.ptr, sz); }();
-            }
+                () @trusted { memcpy(&source, __traits(initSymbol, T).ptr, sz); }();
         }
     }
     else static if (__traits(isStaticArray, T))
@@ -2201,3 +2221,74 @@ pure nothrow @nogc @system unittest
     static assert(!__traits(compiles, f(ncarray)));
     f(move(ncarray));
 }
+
+/**
+ * This is called for a delete statement where the value
+ * being deleted is a pointer to a struct with a destructor
+ * but doesn't have an overloaded delete operator.
+ *
+ * Params:
+ *   p = pointer to the value to be deleted
+ */
+void _d_delstruct(T)(ref T *p)
+{
+    if (p)
+    {
+        debug(PRINTF) printf("_d_delstruct(%p)\n", p);
+
+        import core.memory : GC;
+
+        destroy(*p);
+        GC.free(p);
+        p = null;
+    }
+}
+
+@system unittest
+{
+    int dtors = 0;
+    struct S { ~this() { ++dtors; } }
+
+    S *s = new S();
+    _d_delstruct(s);
+
+    assert(s == null);
+    assert(dtors == 1);
+}
+
+@system unittest
+{
+    int innerDtors = 0;
+    int outerDtors = 0;
+
+    struct Inner { ~this() { ++innerDtors; } }
+    struct Outer
+    {
+        Inner *i1;
+        Inner *i2;
+
+        this(int x)
+        {
+            i1 = new Inner();
+            i2 = new Inner();
+        }
+
+        ~this()
+        {
+            ++outerDtors;
+
+            _d_delstruct(i1);
+            assert(i1 == null);
+
+            _d_delstruct(i2);
+            assert(i2 == null);
+        }
+    }
+
+    Outer *o = new Outer(0);
+    _d_delstruct(o);
+
+    assert(o == null);
+    assert(innerDtors == 2);
+    assert(outerDtors == 1);
+}
diff --git a/libphobos/libdruntime/core/memory.d b/libphobos/libdruntime/core/memory.d
index 3770c13337c..c4df0f2d0dd 100644
--- a/libphobos/libdruntime/core/memory.d
+++ b/libphobos/libdruntime/core/memory.d
@@ -270,7 +270,7 @@ extern(C):
      * reentrant, and must be called once for every call to disable before
      * automatic collections are enabled.
      */
-    pragma(mangle, "gc_enable") static void enable() nothrow; /* FIXME pure */
+    pragma(mangle, "gc_enable") static void enable() nothrow pure;
 
 
     /**
@@ -280,7 +280,7 @@ extern(C):
      * such as during an out of memory condition.  This function is reentrant,
      * but enable must be called once for each call to disable.
      */
-    pragma(mangle, "gc_disable") static void disable() nothrow; /* FIXME pure */
+    pragma(mangle, "gc_disable") static void disable() nothrow pure;
 
 
     /**
@@ -290,14 +290,14 @@ extern(C):
      * and then to reclaim free space.  This action may need to suspend all
      * running threads for at least part of the collection process.
      */
-    pragma(mangle, "gc_collect") static void collect() nothrow; /* FIXME pure */
+    pragma(mangle, "gc_collect") static void collect() nothrow pure;
 
     /**
      * Indicates that the managed memory space be minimized by returning free
      * physical memory to the operating system.  The amount of free memory
      * returned depends on the allocator design and on program behavior.
      */
-    pragma(mangle, "gc_minimize") static void minimize() nothrow; /* FIXME pure */
+    pragma(mangle, "gc_minimize") static void minimize() nothrow pure;
 
 extern(D):
 
@@ -551,7 +551,7 @@ extern(C):
      * Throws:
      *  `OutOfMemoryError` on allocation failure.
      */
-    pragma(mangle, "gc_realloc") static void* realloc(return void* p, size_t sz, uint ba = 0, const TypeInfo ti = null) pure nothrow;
+    pragma(mangle, "gc_realloc") static void* realloc(return scope void* p, size_t sz, uint ba = 0, const TypeInfo ti = null) pure nothrow;
 
     // https://issues.dlang.org/show_bug.cgi?id=13111
     ///
@@ -635,7 +635,7 @@ extern(C):
      * Returns:
      *  The actual number of bytes reserved or zero on error.
      */
-    pragma(mangle, "gc_reserve") static size_t reserve(size_t sz) nothrow; /* FIXME pure */
+    pragma(mangle, "gc_reserve") static size_t reserve(size_t sz) nothrow pure;
 
 
     /**
@@ -807,7 +807,7 @@ extern(C):
      * }
      * ---
      */
-    pragma(mangle, "gc_addRoot") static void addRoot(const void* p) nothrow @nogc; /* FIXME pure */
+    pragma(mangle, "gc_addRoot") static void addRoot(const void* p) nothrow @nogc pure;
 
 
     /**
@@ -818,7 +818,7 @@ extern(C):
      * Params:
      *  p = A pointer into a GC-managed memory block or null.
      */
-    pragma(mangle, "gc_removeRoot") static void removeRoot(const void* p) nothrow @nogc; /* FIXME pure */
+    pragma(mangle, "gc_removeRoot") static void removeRoot(const void* p) nothrow @nogc pure;
 
 
     /**
@@ -849,7 +849,8 @@ extern(C):
      * // rawMemory will be recognized on collection.
      * ---
      */
-    pragma(mangle, "gc_addRange") static void addRange(const void* p, size_t sz, const TypeInfo ti = null) @nogc nothrow; /* FIXME pure */
+    pragma(mangle, "gc_addRange")
+    static void addRange(const void* p, size_t sz, const TypeInfo ti = null) @nogc nothrow pure;
 
 
     /**
@@ -861,7 +862,7 @@ extern(C):
      * Params:
      *  p  = A pointer to a valid memory address or to null.
      */
-    pragma(mangle, "gc_removeRange") static void removeRange(const void* p) nothrow @nogc; /* FIXME pure */
+    pragma(mangle, "gc_removeRange") static void removeRange(const void* p) nothrow @nogc pure;
 
 
     /**
diff --git a/libphobos/libdruntime/core/stdc/stdlib.d b/libphobos/libdruntime/core/stdc/stdlib.d
index 2f11a663eb5..92f8f705540 100644
--- a/libphobos/libdruntime/core/stdc/stdlib.d
+++ b/libphobos/libdruntime/core/stdc/stdlib.d
@@ -26,6 +26,10 @@ else version (TVOS)
 else version (WatchOS)
     version = Darwin;
 
+version (CRuntime_Glibc)
+    version = AlignedAllocSupported;
+else {}
+
 extern (C):
 @system:
 
@@ -166,6 +170,12 @@ void*   realloc(void* ptr, size_t size);
 ///
 void    free(void* ptr);
 
+/// since C11
+version (AlignedAllocSupported)
+{
+    void* aligned_alloc(size_t alignment, size_t size);
+}
+
 ///
 noreturn abort() @safe;
 ///
diff --git a/libphobos/libdruntime/core/stdc/string.d b/libphobos/libdruntime/core/stdc/string.d
index a26811ca623..f15ef851909 100644
--- a/libphobos/libdruntime/core/stdc/string.d
+++ b/libphobos/libdruntime/core/stdc/string.d
@@ -35,31 +35,31 @@ nothrow:
 @nogc:
 
 ///
-inout(void)* memchr(return inout void* s, int c, size_t n) pure;
+inout(void)* memchr(return scope inout void* s, int c, size_t n) pure;
 ///
 int   memcmp(scope const void* s1, scope const void* s2, size_t n) pure;
 ///
-void* memcpy(return void* s1, scope const void* s2, size_t n) pure;
+void* memcpy(return scope void* s1, scope const void* s2, size_t n) pure;
 version (Windows)
 {
     ///
     int memicmp(scope const char* s1, scope const char* s2, size_t n);
 }
 ///
-void* memmove(return void* s1, scope const void* s2, size_t n) pure;
+void* memmove(return scope void* s1, scope const void* s2, size_t n) pure;
 ///
-void* memset(return void* s, int c, size_t n) pure;
+void* memset(return scope void* s, int c, size_t n) pure;
 
 ///
-char*  strcat(return char* s1, scope const char* s2) pure;
+char*  strcat(return scope char* s1, scope const char* s2) pure;
 ///
-inout(char)*  strchr(return inout(char)* s, int c) pure;
+inout(char)*  strchr(return scope inout(char)* s, int c) pure;
 ///
 int    strcmp(scope const char* s1, scope const char* s2) pure;
 ///
 int    strcoll(scope const char* s1, scope const char* s2);
 ///
-char*  strcpy(return char* s1, scope const char* s2) pure;
+char*  strcpy(return scope char* s1, scope const char* s2) pure;
 ///
 size_t strcspn(scope const char* s1, scope const char* s2) pure;
 ///
@@ -70,7 +70,7 @@ char*  strerror(int errnum);
 version (ReturnStrerrorR)
 {
     ///
-    const(char)* strerror_r(int errnum, return char* buf, size_t buflen);
+    const(char)* strerror_r(int errnum, return scope char* buf, size_t buflen);
 }
 // This one is
 else
@@ -80,20 +80,20 @@ else
 ///
 size_t strlen(scope const char* s) pure;
 ///
-char*  strncat(return char* s1, scope const char* s2, size_t n) pure;
+char*  strncat(return scope char* s1, scope const char* s2, size_t n) pure;
 ///
 int    strncmp(scope const char* s1, scope const char* s2, size_t n) pure;
 ///
-char*  strncpy(return char* s1, scope const char* s2, size_t n) pure;
+char*  strncpy(return scope char* s1, scope const char* s2, size_t n) pure;
 ///
-inout(char)*  strpbrk(return inout(char)* s1, scope const char* s2) pure;
+inout(char)*  strpbrk(return scope inout(char)* s1, scope const char* s2) pure;
 ///
-inout(char)*  strrchr(return inout(char)* s, int c) pure;
+inout(char)*  strrchr(return scope inout(char)* s, int c) pure;
 ///
 size_t strspn(scope const char* s1, scope const char* s2) pure;
 ///
-inout(char)*  strstr(return inout(char)* s1, scope const char* s2) pure;
+inout(char)*  strstr(return scope inout(char)* s1, scope const char* s2) pure;
 ///
-char*  strtok(return char* s1, scope const char* s2);
+char*  strtok(return scope char* s1, scope const char* s2);
 ///
 size_t strxfrm(scope char* s1, scope const char* s2, size_t n);
diff --git a/libphobos/libdruntime/core/stdc/wchar_.d b/libphobos/libdruntime/core/stdc/wchar_.d
index 6da5618ada6..e8fb94b11e6 100644
--- a/libphobos/libdruntime/core/stdc/wchar_.d
+++ b/libphobos/libdruntime/core/stdc/wchar_.d
@@ -213,13 +213,13 @@ c_ulong wcstoul(const scope wchar_t* nptr, wchar_t** endptr, int base);
 ulong   wcstoull(const scope wchar_t* nptr, wchar_t** endptr, int base);
 
 ///
-pure wchar_t* wcscpy(return wchar_t* s1, scope const wchar_t* s2);
+pure wchar_t* wcscpy(return scope wchar_t* s1, scope const wchar_t* s2);
 ///
-pure wchar_t* wcsncpy(return wchar_t* s1, scope const wchar_t* s2, size_t n);
+pure wchar_t* wcsncpy(return scope wchar_t* s1, scope const wchar_t* s2, size_t n);
 ///
-pure wchar_t* wcscat(return wchar_t* s1, scope const wchar_t* s2);
+pure wchar_t* wcscat(return scope wchar_t* s1, scope const wchar_t* s2);
 ///
-pure wchar_t* wcsncat(return wchar_t* s1, scope const wchar_t* s2, size_t n);
+pure wchar_t* wcsncat(return scope wchar_t* s1, scope const wchar_t* s2, size_t n);
 ///
 pure int wcscmp(scope const wchar_t* s1, scope const wchar_t* s2);
 ///
@@ -229,32 +229,32 @@ pure int wcsncmp(scope const wchar_t* s1, scope const wchar_t* s2, size_t n);
 ///
 size_t   wcsxfrm(scope wchar_t* s1, scope const wchar_t* s2, size_t n);
 ///
-pure inout(wchar_t)* wcschr(return inout(wchar_t)* s, wchar_t c);
+pure inout(wchar_t)* wcschr(return scope inout(wchar_t)* s, wchar_t c);
 ///
 pure size_t wcscspn(scope const wchar_t* s1, scope const wchar_t* s2);
 ///
-pure inout(wchar_t)* wcspbrk(return inout(wchar_t)* s1, scope const wchar_t* s2);
+pure inout(wchar_t)* wcspbrk(return scope inout(wchar_t)* s1, scope const wchar_t* s2);
 ///
-pure inout(wchar_t)* wcsrchr(return inout(wchar_t)* s, wchar_t c);
+pure inout(wchar_t)* wcsrchr(return scope inout(wchar_t)* s, wchar_t c);
 ///
 pure size_t wcsspn(scope const wchar_t* s1, scope const wchar_t* s2);
 ///
-pure inout(wchar_t)* wcsstr(return inout(wchar_t)* s1, scope const wchar_t* s2);
+pure inout(wchar_t)* wcsstr(return scope inout(wchar_t)* s1, scope const wchar_t* s2);
 ///
-wchar_t* wcstok(return wchar_t* s1, scope const wchar_t* s2, wchar_t** ptr);
+wchar_t* wcstok(return scope wchar_t* s1, scope const wchar_t* s2, wchar_t** ptr);
 ///
 pure size_t wcslen(scope const wchar_t* s);
 
 ///
-pure inout(wchar_t)* wmemchr(return inout wchar_t* s, wchar_t c, size_t n);
+pure inout(wchar_t)* wmemchr(return scope inout wchar_t* s, wchar_t c, size_t n);
 ///
 pure int      wmemcmp(scope const wchar_t* s1, scope const wchar_t* s2, size_t n);
 ///
-pure wchar_t* wmemcpy(return wchar_t* s1, scope const wchar_t* s2, size_t n);
+pure wchar_t* wmemcpy(return scope wchar_t* s1, scope const wchar_t* s2, size_t n);
 ///
-pure wchar_t* wmemmove(return wchar_t* s1, scope const wchar_t* s2, size_t n);
+pure wchar_t* wmemmove(return scope wchar_t* s1, scope const wchar_t* s2, size_t n);
 ///
-pure wchar_t* wmemset(return wchar_t* s, wchar_t c, size_t n);
+pure wchar_t* wmemset(return scope wchar_t* s, wchar_t c, size_t n);
 
 ///
 size_t wcsftime(wchar_t* s, size_t maxsize, const scope wchar_t* format, const scope tm* timeptr);
diff --git a/libphobos/libdruntime/core/stdcpp/exception.d b/libphobos/libdruntime/core/stdcpp/exception.d
index f920057cd06..d65cd8d1832 100644
--- a/libphobos/libdruntime/core/stdcpp/exception.d
+++ b/libphobos/libdruntime/core/stdcpp/exception.d
@@ -19,6 +19,8 @@ version (CppRuntime_Gcc)
     version = GenericBaseException;
 version (CppRuntime_Clang)
     version = GenericBaseException;
+version (CppRuntime_Sun)
+    version = GenericBaseException;
 
 extern (C++, "std"):
 @nogc:
diff --git a/libphobos/libdruntime/core/sync/mutex.d b/libphobos/libdruntime/core/sync/mutex.d
index b153ab9aef0..b848a147460 100644
--- a/libphobos/libdruntime/core/sync/mutex.d
+++ b/libphobos/libdruntime/core/sync/mutex.d
@@ -189,7 +189,7 @@ class Mutex :
             if (pthread_mutex_lock(&m_hndl) == 0)
                 return;
 
-            SyncError syncErr = cast(SyncError) cast(void*) typeid(SyncError).initializer;
+            SyncError syncErr = cast(SyncError) __traits(initSymbol, SyncError).ptr;
             syncErr.msg = "Unable to lock mutex.";
             throw syncErr;
         }
@@ -227,7 +227,7 @@ class Mutex :
             if (pthread_mutex_unlock(&m_hndl) == 0)
                 return;
 
-            SyncError syncErr = cast(SyncError) cast(void*) typeid(SyncError).initializer;
+            SyncError syncErr = cast(SyncError) __traits(initSymbol, SyncError).ptr;
             syncErr.msg = "Unable to unlock mutex.";
             throw syncErr;
         }
diff --git a/libphobos/libdruntime/core/sys/bionic/string.d b/libphobos/libdruntime/core/sys/bionic/string.d
index cbee06c4efe..10a5610ac44 100644
--- a/libphobos/libdruntime/core/sys/bionic/string.d
+++ b/libphobos/libdruntime/core/sys/bionic/string.d
@@ -14,4 +14,4 @@ extern (C):
 nothrow:
 @nogc:
 
-pure void* memmem(return const void* haystack, size_t haystacklen, scope const void* needle, size_t needlelen);
+pure void* memmem(return scope const void* haystack, size_t haystacklen, scope const void* needle, size_t needlelen);
diff --git a/libphobos/libdruntime/core/sys/darwin/mach/nlist.d b/libphobos/libdruntime/core/sys/darwin/mach/nlist.d
index 11e5ced26b7..4d400f207c7 100644
--- a/libphobos/libdruntime/core/sys/darwin/mach/nlist.d
+++ b/libphobos/libdruntime/core/sys/darwin/mach/nlist.d
@@ -222,7 +222,7 @@ enum
  */
 ubyte GET_LIBRARY_ORDINAL(uint n_desc) @safe { return ((n_desc) >> 8) & 0xff; }
 /// Ditto
-ref ushort SET_LIBRARY_ORDINAL(return scope ref ushort n_desc, uint ordinal) @safe
+ref ushort SET_LIBRARY_ORDINAL(return ref ushort n_desc, uint ordinal) @safe
 {
     return n_desc = (((n_desc) & 0x00ff) | (((ordinal) & 0xff) << 8));
 }
diff --git a/libphobos/libdruntime/core/sys/darwin/string.d b/libphobos/libdruntime/core/sys/darwin/string.d
index bd65fde27bc..ac988b58f0d 100644
--- a/libphobos/libdruntime/core/sys/darwin/string.d
+++ b/libphobos/libdruntime/core/sys/darwin/string.d
@@ -27,5 +27,5 @@ nothrow:
 static if (__DARWIN_C_LEVEL >= __DARWIN_C_FULL)
 {
     // ^ __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
-    pure void* memmem(return const void* haystack, size_t haystacklen, scope const void* needle, size_t needlelen);
+    pure void* memmem(return scope const void* haystack, size_t haystacklen, scope const void* needle, size_t needlelen);
 }
diff --git a/libphobos/libdruntime/core/sys/dragonflybsd/string.d b/libphobos/libdruntime/core/sys/dragonflybsd/string.d
index b64178f6562..4b8422748b6 100644
--- a/libphobos/libdruntime/core/sys/dragonflybsd/string.d
+++ b/libphobos/libdruntime/core/sys/dragonflybsd/string.d
@@ -17,6 +17,6 @@ nothrow:
 
 static if (__BSD_VISIBLE)
 {
-    pure void* memmem(return const void* haystack, size_t haystacklen, scope const void* needle, size_t needlelen);
+    pure void* memmem(return scope const void* haystack, size_t haystacklen, scope const void* needle, size_t needlelen);
 }
 
diff --git a/libphobos/libdruntime/core/sys/freebsd/string.d b/libphobos/libdruntime/core/sys/freebsd/string.d
index 3602ea8e86b..459e9115878 100644
--- a/libphobos/libdruntime/core/sys/freebsd/string.d
+++ b/libphobos/libdruntime/core/sys/freebsd/string.d
@@ -17,5 +17,5 @@ nothrow:
 
 static if (__BSD_VISIBLE)
 {
-    pure void* memmem(return const void* haystack, size_t haystacklen, scope const void* needle, size_t needlelen);
+    pure void* memmem(return scope const void* haystack, size_t haystacklen, scope const void* needle, size_t needlelen);
 }
diff --git a/libphobos/libdruntime/core/sys/linux/string.d b/libphobos/libdruntime/core/sys/linux/string.d
index 1b2c8d86a4a..e3c94cf6a8a 100644
--- a/libphobos/libdruntime/core/sys/linux/string.d
+++ b/libphobos/libdruntime/core/sys/linux/string.d
@@ -18,5 +18,5 @@ nothrow:
 
 static if (__USE_GNU)
 {
-    pure void* memmem(return const void* haystack, size_t haystacklen, scope const void* needle, size_t needlelen);
+    pure void* memmem(return scope const void* haystack, size_t haystacklen, scope const void* needle, size_t needlelen);
 }
diff --git a/libphobos/libdruntime/core/sys/linux/syscalls.d b/libphobos/libdruntime/core/sys/linux/syscalls.d
deleted file mode 100644
index 8c653719317..00000000000
--- a/libphobos/libdruntime/core/sys/linux/syscalls.d
+++ /dev/null
@@ -1,745 +0,0 @@
-module core.sys.linux.syscalls;
-
-version (linux):
-extern (C):
-@system:
-nothrow:
-@nogc:
-
-import core.stdc.config : c_long;
-
-version (CoreDdoc)
-{
-    /// Linux system call number from Linux's asm/unistd.h
-    enum SystemCall : c_long;
-}
-else version (X86_64)
-{
-    // https://github.com/torvalds/linux/blob/v4.14/arch/sh/include/uapi/asm/unistd_64.h
-    // https://github.com/torvalds/linux/blob/v4.14/arch/x86/entry/syscalls/syscall_64.tbl
-    enum SystemCall : c_long
-    {
-        read = 0,
-        write = 1,
-        open = 2,
-        close = 3,
-        stat = 4,
-        fstat = 5,
-        lstat = 6,
-        poll = 7,
-        lseek = 8,
-        mmap = 9,
-        mprotect = 10,
-        munmap = 11,
-        brk = 12,
-        rt_sigaction = 13,
-        rt_sigprocmask = 14,
-        rt_sigreturn = 15,
-        ioctl = 16,
-        pread64 = 17,
-        pwrite64 = 18,
-        readv = 19,
-        writev = 20,
-        access = 21,
-        pipe = 22,
-        select = 23,
-        sched_yield = 24,
-        mremap = 25,
-        msync = 26,
-        mincore = 27,
-        madvise = 28,
-        shmget = 29,
-        shmat = 30,
-        shmctl = 31,
-        dup = 32,
-        dup2 = 33,
-        pause = 34,
-        nanosleep = 35,
-        getitimer = 36,
-        alarm = 37,
-        setitimer = 38,
-        getpid = 39,
-        sendfile = 40,
-        socket = 41,
-        connect = 42,
-        accept = 43,
-        sendto = 44,
-        recvfrom = 45,
-        sendmsg = 46,
-        recvmsg = 47,
-        shutdown = 48,
-        bind = 49,
-        listen = 50,
-        getsockname = 51,
-        getpeername = 52,
-        socketpair = 53,
-        setsockopt = 54,
-        getsockopt = 55,
-        clone = 56,
-        fork = 57,
-        vfork = 58,
-        execve = 59,
-        exit = 60,
-        wait4 = 61,
-        kill = 62,
-        uname = 63,
-        semget = 64,
-        semop = 65,
-        semctl = 66,
-        shmdt = 67,
-        msgget = 68,
-        msgsnd = 69,
-        msgrcv = 70,
-        msgctl = 71,
-        fcntl = 72,
-        flock = 73,
-        fsync = 74,
-        fdatasync = 75,
-        truncate = 76,
-        ftruncate = 77,
-        getdents = 78,
-        getcwd = 79,
-        chdir = 80,
-        fchdir = 81,
-        rename = 82,
-        mkdir = 83,
-        rmdir = 84,
-        creat = 85,
-        link = 86,
-        unlink = 87,
-        symlink = 88,
-        readlink = 89,
-        chmod = 90,
-        fchmod = 91,
-        chown = 92,
-        fchown = 93,
-        lchown = 94,
-        umask = 95,
-        gettimeofday = 96,
-        getrlimit = 97,
-        getrusage = 98,
-        sysinfo = 99,
-        times = 100,
-        ptrace = 101,
-        getuid = 102,
-        syslog = 103,
-        getgid = 104,
-        setuid = 105,
-        setgid = 106,
-        geteuid = 107,
-        getegid = 108,
-        setpgid = 109,
-        getppid = 110,
-        getpgrp = 111,
-        setsid = 112,
-        setreuid = 113,
-        setregid = 114,
-        getgroups = 115,
-        setgroups = 116,
-        setresuid = 117,
-        getresuid = 118,
-        setresgid = 119,
-        getresgid = 120,
-        getpgid = 121,
-        setfsuid = 122,
-        setfsgid = 123,
-        getsid = 124,
-        capget = 125,
-        capset = 126,
-        rt_sigpending = 127,
-        rt_sigtimedwait = 128,
-        rt_sigqueueinfo = 129,
-        rt_sigsuspend = 130,
-        sigaltstack = 131,
-        utime = 132,
-        mknod = 133,
-        uselib = 134,
-        personality = 135,
-        ustat = 136,
-        statfs = 137,
-        fstatfs = 138,
-        sysfs = 139,
-        getpriority = 140,
-        setpriority = 141,
-        sched_setparam = 142,
-        sched_getparam = 143,
-        sched_setscheduler = 144,
-        sched_getscheduler = 145,
-        sched_get_priority_max = 146,
-        sched_get_priority_min = 147,
-        sched_rr_get_interval = 148,
-        mlock = 149,
-        munlock = 150,
-        mlockall = 151,
-        munlockall = 152,
-        vhangup = 153,
-        modify_ldt = 154,
-        pivot_root = 155,
-        _sysctl = 156,
-        prctl = 157,
-        arch_prctl = 158,
-        adjtimex = 159,
-        setrlimit = 160,
-        chroot = 161,
-        sync = 162,
-        acct = 163,
-        settimeofday = 164,
-        mount = 165,
-        umount2 = 166,
-        swapon = 167,
-        swapoff = 168,
-        reboot = 169,
-        sethostname = 170,
-        setdomainname = 171,
-        iopl = 172,
-        ioperm = 173,
-        create_module = 174,
-        init_module = 175,
-        delete_module = 176,
-        get_kernel_syms = 177,
-        query_module = 178,
-        quotactl = 179,
-        nfsservctl = 180,
-        getpmsg = 181,
-        putpmsg = 182,
-        afs_syscall = 183,
-        tuxcall = 184,
-        security = 185,
-        gettid = 186,
-        readahead = 187,
-        setxattr = 188,
-        lsetxattr = 189,
-        fsetxattr = 190,
-        getxattr = 191,
-        lgetxattr = 192,
-        fgetxattr = 193,
-        listxattr = 194,
-        llistxattr = 195,
-        flistxattr = 196,
-        removexattr = 197,
-        lremovexattr = 198,
-        fremovexattr = 199,
-        tkill = 200,
-        time = 201,
-        futex = 202,
-        sched_setaffinity = 203,
-        sched_getaffinity = 204,
-        set_thread_area = 205,
-        io_setup = 206,
-        io_destroy = 207,
-        io_getevents = 208,
-        io_submit = 209,
-        io_cancel = 210,
-        get_thread_area = 211,
-        lookup_dcookie = 212,
-        epoll_create = 213,
-        epoll_ctl_old = 214,
-        epoll_wait_old = 215,
-        remap_file_pages = 216,
-        getdents64 = 217,
-        set_tid_address = 218,
-        restart_syscall = 219,
-        semtimedop = 220,
-        fadvise64 = 221,
-        timer_create = 222,
-        timer_settime = 223,
-        timer_gettime = 224,
-        timer_getoverrun = 225,
-        timer_delete = 226,
-        clock_settime = 227,
-        clock_gettime = 228,
-        clock_getres = 229,
-        clock_nanosleep = 230,
-        exit_group = 231,
-        epoll_wait = 232,
-        epoll_ctl = 233,
-        tgkill = 234,
-        utimes = 235,
-        vserver = 236,
-        mbind = 237,
-        set_mempolicy = 238,
-        get_mempolicy = 239,
-        mq_open = 240,
-        mq_unlink = 241,
-        mq_timedsend = 242,
-        mq_timedreceive = 243,
-        mq_notify = 244,
-        mq_getsetattr = 245,
-        kexec_load = 246,
-        waitid = 247,
-        add_key = 248,
-        request_key = 249,
-        keyctl = 250,
-        ioprio_set = 251,
-        ioprio_get = 252,
-        inotify_init = 253,
-        inotify_add_watch = 254,
-        inotify_rm_watch = 255,
-        migrate_pages = 256,
-        openat = 257,
-        mkdirat = 258,
-        mknodat = 259,
-        fchownat = 260,
-        futimesat = 261,
-        newfstatat = 262,
-        unlinkat = 263,
-        renameat = 264,
-        linkat = 265,
-        symlinkat = 266,
-        readlinkat = 267,
-        fchmodat = 268,
-        faccessat = 269,
-        pselect6 = 270,
-        ppoll = 271,
-        unshare = 272,
-        set_robust_list = 273,
-        get_robust_list = 274,
-        splice = 275,
-        tee = 276,
-        sync_file_range = 277,
-        vmsplice = 278,
-        move_pages = 279,
-        utimensat = 280,
-        epoll_pwait = 281,
-        signalfd = 282,
-        timerfd_create = 283,
-        eventfd = 284,
-        fallocate = 285,
-        timerfd_settime = 286,
-        timerfd_gettime = 287,
-        accept4 = 288,
-        signalfd4 = 289,
-        eventfd2 = 290,
-        epoll_create1 = 291,
-        dup3 = 292,
-        pipe2 = 293,
-        inotify_init1 = 294,
-        preadv = 295,
-        pwritev = 296,
-        rt_tgsigqueueinfo = 297,
-        perf_event_open = 298,
-        recvmmsg = 299,
-        fanotify_init = 300,
-        fanotify_mark = 301,
-        prlimit64 = 302,
-        name_to_handle_at = 303,
-        open_by_handle_at = 304,
-        clock_adjtime = 305,
-        syncfs = 306,
-        sendmmsg = 307,
-        setns = 308,
-        getcpu = 309,
-        process_vm_readv = 310,
-        process_vm_writev = 311,
-        kcmp = 312,
-        finit_module = 313,
-        sched_setattr = 314,
-        sched_getattr = 315,
-        renameat2 = 316,
-        seccomp = 317,
-        getrandom = 318,
-        memfd_create = 319,
-        kexec_file_load = 320,
-        bpf = 321,
-        execveat = 322,
-        userfaultfd = 323,
-        membarrier = 324,
-        mlock2 = 325,
-        copy_file_range = 326,
-        preadv2 = 327,
-        pwritev2 = 328,
-        pkey_mprotect = 329,
-        pkey_alloc = 330,
-        pkey_free = 331,
-        statx = 332,
-    }
-}
-else version (X86)
-{
-    // https://github.com/torvalds/linux/blob/master/arch/x86/entry/syscalls/syscall_32.tbl
-    // https://github.com/torvalds/linux/blob/v4.14/arch/sh/include/uapi/asm/unistd_32.h
-    enum SystemCall : c_long
-    {
-        restart_syscall = 0,
-        exit = 1,
-        fork = 2,
-        read = 3,
-        write = 4,
-        open = 5,
-        close = 6,
-        waitpid = 7,
-        creat = 8,
-        link = 9,
-        unlink = 10,
-        execve = 11,
-        chdir = 12,
-        time = 13,
-        mknod = 14,
-        chmod = 15,
-        lchown = 16,
-        break_ = 17,
-        oldstat = 18,
-        lseek = 19,
-        getpid = 20,
-        mount = 21,
-        umount = 22,
-        setuid = 23,
-        getuid = 24,
-        stime = 25,
-        ptrace = 26,
-        alarm = 27,
-        oldfstat = 28,
-        pause = 29,
-        utime = 30,
-        stty = 31,
-        gtty = 32,
-        access = 33,
-        nice = 34,
-        ftime = 35,
-        sync = 36,
-        kill = 37,
-        rename = 38,
-        mkdir = 39,
-        rmdir = 40,
-        dup = 41,
-        pipe = 42,
-        times = 43,
-        prof = 44,
-        brk = 45,
-        setgid = 46,
-        getgid = 47,
-        signal = 48,
-        geteuid = 49,
-        getegid = 50,
-        acct = 51,
-        umount2 = 52,
-        lock = 53,
-        ioctl = 54,
-        fcntl = 55,
-        mpx = 56,
-        setpgid = 57,
-        ulimit = 58,
-        oldolduname = 59,
-        umask = 60,
-        chroot = 61,
-        ustat = 62,
-        dup2 = 63,
-        getppid = 64,
-        getpgrp = 65,
-        setsid = 66,
-        sigaction = 67,
-        sgetmask = 68,
-        ssetmask = 69,
-        setreuid = 70,
-        setregid = 71,
-        sigsuspend = 72,
-        sigpending = 73,
-        sethostname = 74,
-        setrlimit = 75,
-        getrlimit = 76,
-        getrusage = 77,
-        gettimeofday = 78,
-        settimeofday = 79,
-        getgroups = 80,
-        setgroups = 81,
-        select = 82,
-        symlink = 83,
-        oldlstat = 84,
-        readlink = 85,
-        uselib = 86,
-        swapon = 87,
-        reboot = 88,
-        readdir = 89,
-        mmap = 90,
-        munmap = 91,
-        truncate = 92,
-        ftruncate = 93,
-        fchmod = 94,
-        fchown = 95,
-        getpriority = 96,
-        setpriority = 97,
-        profil = 98,
-        statfs = 99,
-        fstatfs = 100,
-        ioperm = 101,
-        socketcall = 102,
-        syslog = 103,
-        setitimer = 104,
-        getitimer = 105,
-        stat = 106,
-        lstat = 107,
-        fstat = 108,
-        olduname = 109,
-        iopl = 110,
-        vhangup = 111,
-        idle = 112,
-        vm86old = 113,
-        wait4 = 114,
-        swapoff = 115,
-        sysinfo = 116,
-        ipc = 117,
-        fsync = 118,
-        sigreturn = 119,
-        clone = 120,
-        setdomainname = 121,
-        uname = 122,
-        modify_ldt = 123,
-        adjtimex = 124,
-        mprotect = 125,
-        sigprocmask = 126,
-        create_module = 127,
-        init_module = 128,
-        delete_module = 129,
-        get_kernel_syms = 130,
-        quotactl = 131,
-        getpgid = 132,
-        fchdir = 133,
-        bdflush = 134,
-        sysfs = 135,
-        personality = 136,
-        afs_syscall = 137,
-        setfsuid = 138,
-        setfsgid = 139,
-        _llseek = 140,
-        getdents = 141,
-        _newselect = 142,
-        flock = 143,
-        msync = 144,
-        readv = 145,
-        writev = 146,
-        getsid = 147,
-        fdatasync = 148,
-        _sysctl = 149,
-        mlock = 150,
-        munlock = 151,
-        mlockall = 152,
-        munlockall = 153,
-        sched_setparam = 154,
-        sched_getparam = 155,
-        sched_setscheduler = 156,
-        sched_getscheduler = 157,
-        sched_yield = 158,
-        sched_get_priority_max = 159,
-        sched_get_priority_min = 160,
-        sched_rr_get_interval = 161,
-        nanosleep = 162,
-        mremap = 163,
-        setresuid = 164,
-        getresuid = 165,
-        vm86 = 166,
-        query_module = 167,
-        poll = 168,
-        nfsservctl = 169,
-        setresgid = 170,
-        getresgid = 171,
-        prctl = 172,
-        rt_sigreturn = 173,
-        rt_sigaction = 174,
-        rt_sigprocmask = 175,
-        rt_sigpending = 176,
-        rt_sigtimedwait = 177,
-        rt_sigqueueinfo = 178,
-        rt_sigsuspend = 179,
-        pread64 = 180,
-        pwrite64 = 181,
-        chown = 182,
-        getcwd = 183,
-        capget = 184,
-        capset = 185,
-        sigaltstack = 186,
-        sendfile = 187,
-        getpmsg = 188,
-        putpmsg = 189,
-        vfork = 190,
-        ugetrlimit = 191,
-        mmap2 = 192,
-        truncate64 = 193,
-        ftruncate64 = 194,
-        stat64 = 195,
-        lstat64 = 196,
-        fstat64 = 197,
-        lchown32 = 198,
-        getuid32 = 199,
-        getgid32 = 200,
-        geteuid32 = 201,
-        getegid32 = 202,
-        setreuid32 = 203,
-        setregid32 = 204,
-        getgroups32 = 205,
-        setgroups32 = 206,
-        fchown32 = 207,
-        setresuid32 = 208,
-        getresuid32 = 209,
-        setresgid32 = 210,
-        getresgid32 = 211,
-        chown32 = 212,
-        setuid32 = 213,
-        setgid32 = 214,
-        setfsuid32 = 215,
-        setfsgid32 = 216,
-        pivot_root = 217,
-        mincore = 218,
-        madvise = 219,
-        getdents64 = 220,
-        fcntl64 = 221,
-        gettid = 224,
-        readahead = 225,
-        setxattr = 226,
-        lsetxattr = 227,
-        fsetxattr = 228,
-        getxattr = 229,
-        lgetxattr = 230,
-        fgetxattr = 231,
-        listxattr = 232,
-        llistxattr = 233,
-        flistxattr = 234,
-        removexattr = 235,
-        lremovexattr = 236,
-        fremovexattr = 237,
-        tkill = 238,
-        sendfile64 = 239,
-        futex = 240,
-        sched_setaffinity = 241,
-        sched_getaffinity = 242,
-        set_thread_area = 243,
-        get_thread_area = 244,
-        io_setup = 245,
-        io_destroy = 246,
-        io_getevents = 247,
-        io_submit = 248,
-        io_cancel = 249,
-        fadvise64 = 250,
-        exit_group = 252,
-        lookup_dcookie = 253,
-        epoll_create = 254,
-        epoll_ctl = 255,
-        epoll_wait = 256,
-        remap_file_pages = 257,
-        set_tid_address = 258,
-        timer_create = 259,
-        timer_settime = 260,
-        timer_gettime = 261,
-        timer_getoverrun = 262,
-        timer_delete = 263,
-        clock_settime = 264,
-        clock_gettime = 265,
-        clock_getres = 266,
-        clock_nanosleep = 267,
-        statfs64 = 268,
-        fstatfs64 = 269,
-        tgkill = 270,
-        utimes = 271,
-        fadvise64_64 = 272,
-        vserver = 273,
-        mbind = 274,
-        get_mempolicy = 275,
-        set_mempolicy = 276,
-        mq_open = 277,
-        mq_unlink = 278,
-        mq_timedsend = 279,
-        mq_timedreceive = 280,
-        mq_notify = 281,
-        mq_getsetattr = 282,
-        kexec_load = 283,
-        waitid = 284,
-        add_key = 286,
-        request_key = 287,
-        keyctl = 288,
-        ioprio_set = 289,
-        ioprio_get = 290,
-        inotify_init = 291,
-        inotify_add_watch = 292,
-        inotify_rm_watch = 293,
-        migrate_pages = 294,
-        openat = 295,
-        mkdirat = 296,
-        mknodat = 297,
-        fchownat = 298,
-        futimesat = 299,
-        fstatat64 = 300,
-        unlinkat = 301,
-        renameat = 302,
-        linkat = 303,
-        symlinkat = 304,
-        readlinkat = 305,
-        fchmodat = 306,
-        faccessat = 307,
-        pselect6 = 308,
-        ppoll = 309,
-        unshare = 310,
-        set_robust_list = 311,
-        get_robust_list = 312,
-        splice = 313,
-        sync_file_range = 314,
-        tee = 315,
-        vmsplice = 316,
-        move_pages = 317,
-        getcpu = 318,
-        epoll_pwait = 319,
-        utimensat = 320,
-        signalfd = 321,
-        timerfd_create = 322,
-        eventfd = 323,
-        fallocate = 324,
-        timerfd_settime = 325,
-        timerfd_gettime = 326,
-        signalfd4 = 327,
-        eventfd2 = 328,
-        epoll_create1 = 329,
-        dup3 = 330,
-        pipe2 = 331,
-        inotify_init1 = 332,
-        preadv = 333,
-        pwritev = 334,
-        rt_tgsigqueueinfo = 335,
-        perf_event_open = 336,
-        recvmmsg = 337,
-        fanotify_init = 338,
-        fanotify_mark = 339,
-        prlimit64 = 340,
-        name_to_handle_at = 341,
-        open_by_handle_at = 342,
-        clock_adjtime = 343,
-        syncfs = 344,
-        sendmmsg = 345,
-        setns = 346,
-        process_vm_readv = 347,
-        process_vm_writev = 348,
-        kcmp = 349,
-        finit_module = 350,
-        sched_setattr = 351,
-        sched_getattr = 352,
-        renameat2 = 353,
-        seccomp = 354,
-        getrandom = 355,
-        memfd_create = 356,
-        bpf = 357,
-        execveat = 358,
-        socket = 359,
-        socketpair = 360,
-        bind = 361,
-        connect = 362,
-        listen = 363,
-        accept4 = 364,
-        getsockopt = 365,
-        setsockopt = 366,
-        getsockname = 367,
-        getpeername = 368,
-        sendto = 369,
-        sendmsg = 370,
-        recvfrom = 371,
-        recvmsg = 372,
-        shutdown = 373,
-        userfaultfd = 374,
-        membarrier = 375,
-        mlock2 = 376,
-        copy_file_range = 377,
-        preadv2 = 378,
-        pwritev2 = 379,
-        pkey_mprotect = 380,
-        pkey_alloc = 381,
-        pkey_free = 382,
-        statx = 383,
-        arch_prctl = 384,
-    }
-}
diff --git a/libphobos/libdruntime/core/sys/linux/unistd.d b/libphobos/libdruntime/core/sys/linux/unistd.d
index 1ef16c12689..48457467005 100644
--- a/libphobos/libdruntime/core/sys/linux/unistd.d
+++ b/libphobos/libdruntime/core/sys/linux/unistd.d
@@ -1,20 +1,16 @@
 module core.sys.linux.unistd;
 
+public import core.sys.posix.unistd;
+
 version (linux):
-extern (C):
+extern(C):
 nothrow:
 @system:
-@nogc:
-
-public import core.sys.posix.unistd;
-public import core.sys.linux.syscalls : SystemCall;
-import core.stdc.config : c_long;
 
 // Additional seek constants for sparse file handling
 // from Linux's unistd.h, stdio.h, and linux/fs.h
 // (see http://man7.org/linux/man-pages/man2/lseek.2.html)
-enum
-{
+enum {
     /// Offset is relative to the next location containing data
     SEEK_DATA = 3,
     /// Offset is relative to the next hole (or EOF if file is not sparse)
@@ -26,17 +22,3 @@ char* getpass(const(char)* prompt);
 
 // Exit all threads in a process
 void exit_group(int status);
-
-/**
-Invoke system call specified by number, passing it the remaining arguments.
-This is completely system-dependent, and not often useful.
-
-In Unix, `syscall' sets `errno' for all errors and most calls return -1
-for errors; in many systems you cannot pass arguments or get return
-values for all system calls (`pipe', `fork', and `getppid' typically
-among them).
-
-In Mach, all system calls take normal arguments and always return an
-error code (zero for success).
-*/
-c_long syscall(SystemCall number, ...) @nogc nothrow;
diff --git a/libphobos/libdruntime/core/sys/netbsd/string.d b/libphobos/libdruntime/core/sys/netbsd/string.d
index ab9ced80cf1..f1281da275b 100644
--- a/libphobos/libdruntime/core/sys/netbsd/string.d
+++ b/libphobos/libdruntime/core/sys/netbsd/string.d
@@ -17,5 +17,5 @@ nothrow:
 
 static if (_NETBSD_SOURCE)
 {
-    pure void* memmem(return const void* haystack, size_t haystacklen, scope const void* needle, size_t needlelen);
+    pure void* memmem(return scope const void* haystack, size_t haystacklen, scope const void* needle, size_t needlelen);
 }
diff --git a/libphobos/libdruntime/core/sys/openbsd/string.d b/libphobos/libdruntime/core/sys/openbsd/string.d
index 131e67727e8..4480c94ac37 100644
--- a/libphobos/libdruntime/core/sys/openbsd/string.d
+++ b/libphobos/libdruntime/core/sys/openbsd/string.d
@@ -18,7 +18,7 @@ nothrow:
 static if (__BSD_VISIBLE)
 {
     void explicit_bzero(void*, size_t);
-    pure void* memmem(return const void* haystack, size_t haystacklen, scope const void* needle, size_t needlelen);
+    pure void* memmem(return scope const void* haystack, size_t haystacklen, scope const void* needle, size_t needlelen);
     void* memrchr(scope const void*, int, size_t);
     size_t strlcat(char*, scope const char*, size_t);
     size_t strlcpy(char*, scope const char*, size_t);
diff --git a/libphobos/libdruntime/core/sys/posix/signal.d b/libphobos/libdruntime/core/sys/posix/signal.d
index 0dce8c53f31..32e51561562 100644
--- a/libphobos/libdruntime/core/sys/posix/signal.d
+++ b/libphobos/libdruntime/core/sys/posix/signal.d
@@ -513,15 +513,21 @@ else version (DragonFlyBSD)
 }
 else version (Solaris)
 {
+    //SIGABRT (defined in core.stdc.signal)
     enum SIGALRM = 14;
     enum SIGBUS = 10;
     enum SIGCHLD = 18;
     enum SIGCONT = 25;
+    //SIGFPE (defined in core.stdc.signal)
     enum SIGHUP = 1;
+    //SIGILL (defined in core.stdc.signal)
+    //SIGINT (defined in core.stdc.signal)
     enum SIGKILL = 9;
     enum SIGPIPE = 13;
     enum SIGQUIT = 3;
+    //SIGSEGV (defined in core.stdc.signal)
     enum SIGSTOP = 23;
+    //SIGTERM (defined in core.stdc.signal)
     enum SIGTSTP = 24;
     enum SIGTTIN = 26;
     enum SIGTTOU = 27;
@@ -1339,6 +1345,10 @@ else version (Solaris)
         uint[4] __bits;
     }
 
+    enum SIG_BLOCK = 1;
+    enum SIG_UNBLOCK = 2;
+    enum SIG_SETMASK = 3;
+
     struct siginfo_t
     {
         int si_signo;
@@ -1427,6 +1437,18 @@ else version (Solaris)
         ___data __data;
     }
 
+    enum SI_NOINFO  = 32767;
+    enum SI_DTRACE  = 2050;
+    enum SI_RCTL    = 2049;
+    enum SI_USER    = 0;
+    enum SI_LWP     = -1;
+    enum SI_QUEUE   = -2;
+    enum SI_TIMER   = -3;
+    enum SI_ASYNCIO = -4;
+    enum SI_MESGQ   = -5;
+
+    enum SIGIO = SIGPOLL;
+
     int kill(pid_t, int);
     int sigaction(int, const scope sigaction_t*, sigaction_t*);
     int sigaddset(sigset_t*, int);
@@ -2833,9 +2855,9 @@ else version (Solaris)
     enum SIGPROF = 29;
     enum SIGSYS = 12;
     enum SIGTRAP = 5;
-    enum SIGVTALRM = 31;
+    enum SIGVTALRM = 28;
     enum SIGXCPU = 30;
-    enum SIGXFSZ = 25;
+    enum SIGXFSZ = 31;
 
     enum
     {
diff --git a/libphobos/libdruntime/core/sys/posix/string.d b/libphobos/libdruntime/core/sys/posix/string.d
index b9e1c1c88c2..79d25624e2a 100644
--- a/libphobos/libdruntime/core/sys/posix/string.d
+++ b/libphobos/libdruntime/core/sys/posix/string.d
@@ -31,11 +31,11 @@ public import core.sys.posix.locale : locale_t;
 public import core.stdc.string;
 
 /// Copy string until character found
-void*  memccpy(return void* dst, scope const void* src, int c, size_t n) pure;
+void*  memccpy(return scope void* dst, scope const void* src, int c, size_t n) pure;
 /// Copy string (including terminating '\0')
-char*  stpcpy(return char* dst, scope const char* src) pure;
+char*  stpcpy(return scope char* dst, scope const char* src) pure;
 /// Ditto
-char*  stpncpy(return char* dst, const char* src, size_t len) pure;
+char*  stpncpy(return scope char* dst, const char* src, size_t len) pure;
 /// Compare strings according to current collation
 int    strcoll_l(scope const char* s1, scope const char* s2, locale_t locale);
 ///
@@ -47,6 +47,6 @@ size_t strnlen(scope const char* str, size_t maxlen) pure;
 /// System signal messages
 const(char)*  strsignal(int);
 /// Isolate sequential tokens in a null-terminated string
-char*  strtok_r(return char* str, scope const char* sep, char** context) pure;
+char*  strtok_r(return scope char* str, scope const char* sep, char** context) pure;
 /// Transform a string under locale
 size_t strxfrm_l(char* s1, scope const char* s2, size_t n, locale_t locale);
diff --git a/libphobos/libdruntime/core/sys/posix/sys/socket.d b/libphobos/libdruntime/core/sys/posix/sys/socket.d
index de51c6a4746..6e0cfd3ac3d 100644
--- a/libphobos/libdruntime/core/sys/posix/sys/socket.d
+++ b/libphobos/libdruntime/core/sys/posix/sys/socket.d
@@ -217,7 +217,7 @@ version (CRuntime_Glibc)
     }
     else
     {
-        extern (D) inout(ubyte)*   CMSG_DATA( return inout(cmsghdr)* cmsg ) pure nothrow @nogc { return cast(ubyte*)( cmsg + 1 ); }
+        extern (D) inout(ubyte)*   CMSG_DATA( return scope inout(cmsghdr)* cmsg ) pure nothrow @nogc { return cast(ubyte*)( cmsg + 1 ); }
     }
 
     private inout(cmsghdr)* __cmsg_nxthdr(inout(msghdr)*, inout(cmsghdr)*) pure nothrow @nogc;
diff --git a/libphobos/libdruntime/core/sys/solaris/sys/elf.d b/libphobos/libdruntime/core/sys/solaris/sys/elf.d
index 7da26317d35..7a46d520cc3 100644
--- a/libphobos/libdruntime/core/sys/solaris/sys/elf.d
+++ b/libphobos/libdruntime/core/sys/solaris/sys/elf.d
@@ -393,7 +393,7 @@ enum SHF_LINK_ORDER       = 0x80;
 enum SHF_OS_NONCONFORMING = 0x100;
 enum SHF_GROUP            = 0x200;
 enum SHF_TLS              = 0x400;
-
+enum SHF_COMPRESSED       = 0x800;
 enum SHF_MASKOS = 0x0ff00000;
 
 enum SHF_MASKPROC = 0xf0000000;
@@ -656,3 +656,6 @@ enum NT_ZONENAME   = 21;
 enum NT_FDINFO     = 22;
 enum NT_SPYMASTER  = 23;
 enum NT_NUM        = 23;
+
+enum SHF_ORDERED = 0x40000000;
+enum SHF_EXCLUDE = 0x80000000;
diff --git a/libphobos/libdruntime/core/sys/solaris/sys/elf_386.d b/libphobos/libdruntime/core/sys/solaris/sys/elf_386.d
index 0c8198513d0..9927b64aec9 100644
--- a/libphobos/libdruntime/core/sys/solaris/sys/elf_386.d
+++ b/libphobos/libdruntime/core/sys/solaris/sys/elf_386.d
@@ -52,9 +52,6 @@ enum R_386_NUM          = 39;
 
 enum ELF_386_MAXPGSZ = 0x10000;
 
-enum SHF_ORDERED = 0x40000000;
-enum SHF_EXCLUDE = 0x80000000;
-
 enum SHN_BEFORE = 0xff00;
 enum SHN_AFTER  = 0xff01;
 
diff --git a/libphobos/libdruntime/core/sys/solaris/sys/elf_SPARC.d b/libphobos/libdruntime/core/sys/solaris/sys/elf_SPARC.d
index 81d02347598..e43bd405b8a 100644
--- a/libphobos/libdruntime/core/sys/solaris/sys/elf_SPARC.d
+++ b/libphobos/libdruntime/core/sys/solaris/sys/elf_SPARC.d
@@ -118,9 +118,6 @@ enum ELF_SPARCV9_MAXPGSZ = 0x100000;
 
 enum SHT_SPARC_GOTDATA = 0x70000000;
 
-enum SHF_ORDERED = 0x40000000;
-enum SHF_EXCLUDE = 0x80000000;
-
 enum SHN_BEFORE = 0xff00;
 enum SHN_AFTER  =  0xff01;
 
diff --git a/libphobos/libdruntime/core/sys/windows/dbghelp.d b/libphobos/libdruntime/core/sys/windows/dbghelp.d
index 9848fb99115..96698e8f0f9 100644
--- a/libphobos/libdruntime/core/sys/windows/dbghelp.d
+++ b/libphobos/libdruntime/core/sys/windows/dbghelp.d
@@ -39,7 +39,8 @@ extern(Windows)
     alias BOOL         function(HANDLE hProcess, DWORD64 Address, DWORD64 *Displacement, IMAGEHLP_SYMBOLA64 *Symbol) SymGetSymFromAddr64Func;
     alias DWORD        function(PCSTR DecoratedName, PSTR UnDecoratedName, DWORD UndecoratedLength, DWORD Flags) UnDecorateSymbolNameFunc;
     alias DWORD64      function(HANDLE hProcess, HANDLE hFile, PCSTR ImageName, PCSTR ModuleName, DWORD64 BaseOfDll, DWORD SizeOfDll) SymLoadModule64Func;
-    alias BOOL         function(HANDLE HProcess, PTSTR SearchPath, DWORD SearchPathLength) SymGetSearchPathFunc;
+    alias BOOL         function(HANDLE hProcess, PSTR SearchPath, DWORD SearchPathLength) SymGetSearchPathFunc;
+    alias BOOL         function(HANDLE hProcess, PCSTR SearchPath) SymSetSearchPathFunc;
     alias BOOL         function(HANDLE hProcess, DWORD64 Address) SymUnloadModule64Func;
     alias BOOL         function(HANDLE hProcess, ULONG ActionCode, ulong CallbackContext, ulong UserContext) PSYMBOL_REGISTERED_CALLBACK64;
     alias BOOL         function(HANDLE hProcess, PSYMBOL_REGISTERED_CALLBACK64 CallbackFunction, ulong UserContext) SymRegisterCallback64Func;
@@ -61,6 +62,7 @@ struct DbgHelp
     UnDecorateSymbolNameFunc UnDecorateSymbolName;
     SymLoadModule64Func      SymLoadModule64;
     SymGetSearchPathFunc     SymGetSearchPath;
+    SymSetSearchPathFunc     SymSetSearchPath;
     SymUnloadModule64Func    SymUnloadModule64;
     SymRegisterCallback64Func SymRegisterCallback64;
     ImagehlpApiVersionFunc   ImagehlpApiVersion;
@@ -84,6 +86,7 @@ struct DbgHelp
             sm_inst.UnDecorateSymbolName     = cast(UnDecorateSymbolNameFunc) GetProcAddress(sm_hndl,"UnDecorateSymbolName");
             sm_inst.SymLoadModule64          = cast(SymLoadModule64Func) GetProcAddress(sm_hndl,"SymLoadModule64");
             sm_inst.SymGetSearchPath         = cast(SymGetSearchPathFunc) GetProcAddress(sm_hndl,"SymGetSearchPath");
+            sm_inst.SymSetSearchPath         = cast(SymSetSearchPathFunc) GetProcAddress(sm_hndl,"SymSetSearchPath");
             sm_inst.SymUnloadModule64        = cast(SymUnloadModule64Func) GetProcAddress(sm_hndl,"SymUnloadModule64");
             sm_inst.SymRegisterCallback64    = cast(SymRegisterCallback64Func) GetProcAddress(sm_hndl, "SymRegisterCallback64");
             sm_inst.ImagehlpApiVersion       = cast(ImagehlpApiVersionFunc) GetProcAddress(sm_hndl, "ImagehlpApiVersion");
@@ -91,7 +94,8 @@ struct DbgHelp
                     sm_inst.SymSetOptions && sm_inst.SymFunctionTableAccess64 && sm_inst.SymGetLineFromAddr64 &&
                     sm_inst.SymGetModuleBase64 && sm_inst.SymGetModuleInfo64 && sm_inst.SymGetSymFromAddr64 &&
                     sm_inst.UnDecorateSymbolName && sm_inst.SymLoadModule64 && sm_inst.SymGetSearchPath &&
-                    sm_inst.SymUnloadModule64 && sm_inst.SymRegisterCallback64 && sm_inst.ImagehlpApiVersion);
+                    sm_inst.SymSetSearchPath && sm_inst.SymUnloadModule64 && sm_inst.SymRegisterCallback64 &&
+                    sm_inst.ImagehlpApiVersion);
 
             return &sm_inst;
         }
diff --git a/libphobos/libdruntime/core/thread/osthread.d b/libphobos/libdruntime/core/thread/osthread.d
index b7dde9387af..fe4d24fafce 100644
--- a/libphobos/libdruntime/core/thread/osthread.d
+++ b/libphobos/libdruntime/core/thread/osthread.d
@@ -719,7 +719,7 @@ class Thread : ThreadBase
                     // the effective maximum.
 
                     // maxupri
-                    result.PRIORITY_MIN = -clinfo[0];
+                    result.PRIORITY_MIN = -cast(int)(clinfo[0]);
                     // by definition
                     result.PRIORITY_DEFAULT = 0;
                 }
@@ -2196,8 +2196,7 @@ extern (C) void thread_init() @nogc
         status = sem_init( &suspendCount, 0, 0 );
         assert( status == 0 );
     }
-    if (typeid(Thread).initializer.ptr)
-        _mainThreadStore[] = typeid(Thread).initializer[];
+    _mainThreadStore[] = __traits(initSymbol, Thread)[];
     Thread.sm_main = attachThread((cast(Thread)_mainThreadStore.ptr).__ctor());
 }
 
diff --git a/libphobos/libdruntime/core/thread/threadbase.d b/libphobos/libdruntime/core/thread/threadbase.d
index 4592bf1d975..9cee4d8d77d 100644
--- a/libphobos/libdruntime/core/thread/threadbase.d
+++ b/libphobos/libdruntime/core/thread/threadbase.d
@@ -771,10 +771,7 @@ package void thread_term_tpl(ThreadT, MainThreadStore)(ref MainThreadStore _main
     // destruct manually as object.destroy is not @nogc
     (cast(ThreadT) cast(void*) ThreadBase.sm_main).__dtor();
     _d_monitordelete_nogc(ThreadBase.sm_main);
-    if (typeid(ThreadT).initializer.ptr)
-        _mainThreadStore[] = typeid(ThreadT).initializer[];
-    else
-        (cast(ubyte[])_mainThreadStore)[] = 0;
+    _mainThreadStore[] = __traits(initSymbol, ThreadT)[];
     ThreadBase.sm_main = null;
 
     assert(ThreadBase.sm_tbeg && ThreadBase.sm_tlen == 1);
diff --git a/libphobos/libdruntime/object.d b/libphobos/libdruntime/object.d
index a079e0e73e9..fee19ae65f0 100644
--- a/libphobos/libdruntime/object.d
+++ b/libphobos/libdruntime/object.d
@@ -3485,7 +3485,7 @@ enum immutable(void)* rtinfoHasPointers = cast(void*)1;
 
 // Helper functions
 
-private inout(TypeInfo) getElement(return inout TypeInfo value) @trusted pure nothrow
+private inout(TypeInfo) getElement(return scope inout TypeInfo value) @trusted pure nothrow
 {
     TypeInfo element = cast() value;
     for (;;)
@@ -4215,8 +4215,8 @@ void destroy(bool initialize = true, T)(T obj) if (is(T == class))
 
         static if (initialize)
         {
-            enum classSize = __traits(classInstanceSize, T);
-            (cast(void*)obj)[0 .. classSize] = typeid(T).initializer[];
+            const initializer = __traits(initSymbol, T);
+            (cast(void*)obj)[0 .. initializer.length] = initializer[];
         }
     }
     else
@@ -4651,6 +4651,8 @@ public import core.internal.array.construction : _d_arrayctor;
 public import core.internal.array.construction : _d_arraysetctor;
 public import core.internal.array.capacity: _d_arraysetlengthTImpl;
 
+public import core.lifetime : _d_delstruct;
+
 public import core.internal.dassert: _d_assert_fail;
 
 public import core.internal.destruction: __ArrayDtor;
diff --git a/libphobos/libdruntime/rt/aaA.d b/libphobos/libdruntime/rt/aaA.d
index 6ff93f76da4..0c38622a879 100644
--- a/libphobos/libdruntime/rt/aaA.d
+++ b/libphobos/libdruntime/rt/aaA.d
@@ -287,7 +287,7 @@ TypeInfo_Struct fakeEntryTI(ref Impl aa, const TypeInfo keyti, const TypeInfo va
     void* p = GC.malloc(sizeti + (2 + rtisize) * (void*).sizeof);
     import core.stdc.string : memcpy;
 
-    memcpy(p, typeid(TypeInfo_Struct).initializer().ptr, sizeti);
+    memcpy(p, __traits(initSymbol, TypeInfo_Struct).ptr, sizeti);
 
     auto ti = cast(TypeInfo_Struct) p;
     auto extra = cast(TypeInfo*)(p + sizeti);
@@ -853,7 +853,7 @@ struct Range
 
 extern (C) pure nothrow @nogc @safe
 {
-    Range _aaRange(return AA aa)
+    Range _aaRange(return scope AA aa)
     {
         if (!aa)
             return Range();
diff --git a/libphobos/libdruntime/rt/cast_.d b/libphobos/libdruntime/rt/cast_.d
index dcb4438c700..1604510b427 100644
--- a/libphobos/libdruntime/rt/cast_.d
+++ b/libphobos/libdruntime/rt/cast_.d
@@ -36,7 +36,7 @@ extern (D) private bool areClassInfosEqual(scope const ClassInfo a, scope const
  *      If it is null, return null.
  *      Else, undefined crash
  */
-Object _d_toObject(return void* p)
+Object _d_toObject(return scope void* p)
 {
     if (!p)
         return null;
diff --git a/libphobos/libdruntime/rt/config.d b/libphobos/libdruntime/rt/config.d
index f7682f31b63..a6605f4d603 100644
--- a/libphobos/libdruntime/rt/config.d
+++ b/libphobos/libdruntime/rt/config.d
@@ -101,6 +101,9 @@ string rt_cmdlineOption(string opt, scope rt_configCallBack dg) @nogc nothrow
     {
         foreach (a; rt_args)
         {
+            if (a == "--")
+                break;
+
             if (a.length >= opt.length + 7 && a[0..6] == "--DRT-" &&
                 a[6 .. 6 + opt.length] == opt && a[6 + opt.length] == '=')
             {
diff --git a/libphobos/libdruntime/rt/lifetime.d b/libphobos/libdruntime/rt/lifetime.d
index f1a9d873860..1f7a81de80f 100644
--- a/libphobos/libdruntime/rt/lifetime.d
+++ b/libphobos/libdruntime/rt/lifetime.d
@@ -181,7 +181,7 @@ extern (C) void _d_delstruct(void** p, TypeInfo_Struct inf) @weak
 }
 
 // strip const/immutable/shared/inout from type info
-inout(TypeInfo) unqualify(return inout(TypeInfo) cti) pure nothrow @nogc
+inout(TypeInfo) unqualify(return scope inout(TypeInfo) cti) pure nothrow @nogc
 {
     TypeInfo ti = cast() cti;
     while (ti)
@@ -381,7 +381,7 @@ size_t __arrayAllocLength(ref BlkInfo info, const TypeInfo tinext) pure nothrow
 /**
   get the start of the array for the given block
   */
-void *__arrayStart(return BlkInfo info) nothrow pure
+void *__arrayStart(return scope BlkInfo info) nothrow pure
 {
     return info.base + ((info.size & BIGLENGTHMASK) ? LARGEPREFIX : 0);
 }
diff --git a/libphobos/libdruntime/rt/monitor_.d b/libphobos/libdruntime/rt/monitor_.d
index 6bfce635c72..763f4392822 100644
--- a/libphobos/libdruntime/rt/monitor_.d
+++ b/libphobos/libdruntime/rt/monitor_.d
@@ -264,7 +264,7 @@ struct Monitor
 
 private:
 
-@property ref shared(Monitor*) monitor(return Object h) pure nothrow @nogc
+@property ref shared(Monitor*) monitor(return scope Object h) pure nothrow @nogc
 {
     return *cast(shared Monitor**)&h.__monitor;
 }
diff --git a/libphobos/src/MERGE b/libphobos/src/MERGE
index 29bcf33c01f..68fefcb1ae4 100644
--- a/libphobos/src/MERGE
+++ b/libphobos/src/MERGE
@@ -1,4 +1,4 @@
-574bf883b790340fb753d6542ec48a3ba3e6cb82
+12329adb67fb43891d6e4e543e7257bc34db0aa7
 
 The first line of this file holds the git revision number of the last
 merge done from the dlang/phobos repository.
diff --git a/libphobos/src/std/algorithm/iteration.d b/libphobos/src/std/algorithm/iteration.d
index 9e728e4622f..af665c41197 100644
--- a/libphobos/src/std/algorithm/iteration.d
+++ b/libphobos/src/std/algorithm/iteration.d
@@ -3595,7 +3595,6 @@ if (isInputRange!RoR && isInputRange!(ElementType!RoR)
     assert(res.equal("cba"));
 }
 
-
 /// Ditto
 auto joiner(RoR)(RoR r)
 if (isInputRange!RoR && isInputRange!(ElementType!RoR))
@@ -3621,14 +3620,32 @@ if (isInputRange!RoR && isInputRange!(ElementType!RoR))
                 _currentBack = typeof(_currentBack).init;
         }
 
+        void replaceCurrent(typeof(_current) current) @trusted
+        {
+            import core.lifetime : move;
+
+            current.move(_current);
+        }
+
+        static if (isBidirectional)
+        {
+            void replaceCurrentBack(typeof(_currentBack) currentBack) @trusted
+            {
+                import core.lifetime : move;
+
+                currentBack.move(_currentBack);
+            }
+        }
+
     public:
         this(RoR r)
         {
             _items = r;
+            // field _current must be initialized in constructor, because it is nested struct
+            _current = typeof(_current).init;
 
             static if (isBidirectional && hasNested!Result)
                 _currentBack = typeof(_currentBack).init;
-            // field _current must be initialized in constructor, because it is nested struct
             mixin(popFrontEmptyElements);
             static if (isBidirectional)
                 mixin(popBackEmptyElements);
@@ -3673,13 +3690,13 @@ if (isInputRange!RoR && isInputRange!(ElementType!RoR))
                 // consumed when a .save'd copy of ourselves is iterated over. So
                 // we need to .save each subrange we traverse.
                 static if (isForwardRange!RoR && isForwardRange!(ElementType!RoR))
-                    _current = _items.front.save;
+                    replaceCurrent(_items.front.save);
                 else
-                    _current = _items.front;
+                    replaceCurrent(_items.front);
             }
             else
             {
-                _current = typeof(_current).init;
+                replaceCurrent(typeof(_current).init);
             }
         };
 
@@ -3696,9 +3713,9 @@ if (isInputRange!RoR && isInputRange!(ElementType!RoR))
                 static if (isBidirectional)
                 {
                     static if (is(typeof(null) : typeof(_currentBack)))
-                        r._currentBack = _currentBack is null ? null : _currentBack.save;
+                        r.replaceCurrentBack(_currentBack is null ? null : _currentBack.save);
                     else
-                        r._currentBack = _currentBack.save;
+                        r.replaceCurrentBack(_currentBack.save);
                     r.reachedFinalElement = reachedFinalElement;
                 }
                 return r;
@@ -3784,22 +3801,22 @@ if (isInputRange!RoR && isInputRange!(ElementType!RoR))
                     static if (isForwardRange!RoR && isForwardRange!(ElementType!RoR))
                     {
                         if (reachedFinalElement)
-                            _current = _items.back.save;
+                            replaceCurrent(_items.back.save);
                         else
-                            _currentBack = _items.back.save;
+                            replaceCurrentBack(_items.back.save);
                     }
                     else
                     {
                         if (reachedFinalElement)
-                            _current = _items.back;
+                            replaceCurrent(_items.back);
                         else
-                            _currentBack = _items.back;
+                            replaceCurrentBack(_items.back);
                     }
                 }
                 else
                 {
-                    _current = typeof(_current).init;
-                    _currentBack = typeof(_currentBack).init;
+                    replaceCurrent(typeof(_current).init);
+                    replaceCurrentBack(typeof(_currentBack).init);
                 }
             };
 
@@ -4232,6 +4249,15 @@ if (isInputRange!RoR && isInputRange!(ElementType!RoR))
     assert([[0]].joiner.save.back == 0);
 }
 
+// https://issues.dlang.org/show_bug.cgi?id=22561
+@safe pure unittest
+{
+    import std.range : only;
+
+    static immutable struct S { int[] array; }
+    assert([only(S(null))].joiner.front == S(null));
+}
+
 /++
 Implements the homonym function (also known as `accumulate`, $(D
 compress), `inject`, or `foldl`) present in various programming
diff --git a/libphobos/src/std/algorithm/mutation.d b/libphobos/src/std/algorithm/mutation.d
index 07cbb9b9823..22b7b98c229 100644
--- a/libphobos/src/std/algorithm/mutation.d
+++ b/libphobos/src/std/algorithm/mutation.d
@@ -886,31 +886,13 @@ if (isInputRange!Range && hasLvalueElements!Range && hasAssignableElements!Range
     static if (hasElaborateAssign!T)
     {
         import std.algorithm.internal : addressOf;
-        //Elaborate opAssign. Must go the memcpy road.
-        //We avoid calling emplace here, because our goal is to initialize to
-        //the static state of T.init,
-        //So we want to avoid any un-necassarilly CC'ing of T.init
+        //Elaborate opAssign. Must go the memcpy/memset road.
         static if (!__traits(isZeroInit, T))
         {
-            auto p = typeid(T).initializer();
             for ( ; !range.empty ; range.popFront() )
             {
-                static if (__traits(isStaticArray, T))
-                {
-                    // static array initializer only contains initialization
-                    // for one element of the static array.
-                    auto elemp = cast(void *) addressOf(range.front);
-                    auto endp = elemp + T.sizeof;
-                    while (elemp < endp)
-                    {
-                        memcpy(elemp, p.ptr, p.length);
-                        elemp += p.length;
-                    }
-                }
-                else
-                {
-                    memcpy(addressOf(range.front), p.ptr, T.sizeof);
-                }
+                import core.internal.lifetime : emplaceInitializer;
+                emplaceInitializer(range.front);
             }
         }
         else
@@ -1456,10 +1438,7 @@ private void moveEmplaceImpl(T)(ref scope T target, ref return scope T source)
             static if (__traits(isZeroInit, T))
                 () @trusted { memset(&source, 0, sz); }();
             else
-            {
-                auto init = typeid(T).initializer();
-                () @trusted { memcpy(&source, init.ptr, sz); }();
-            }
+                () @trusted { memcpy(&source, __traits(initSymbol, T).ptr, sz); }();
         }
     }
     else static if (isStaticArray!T)
diff --git a/libphobos/src/std/algorithm/sorting.d b/libphobos/src/std/algorithm/sorting.d
index f2877ccbdf4..ee68b234b15 100644
--- a/libphobos/src/std/algorithm/sorting.d
+++ b/libphobos/src/std/algorithm/sorting.d
@@ -3121,14 +3121,14 @@ if (isRandomAccessRange!R && hasLength!R && hasSwappableElements!R &&
     else
         static assert(false, "`transform` returns an unsortable qualified type: " ~ TB.stringof);
 
-    static trustedMalloc(size_t len) @trusted
+    static trustedMalloc()(size_t len) @trusted
     {
         import core.checkedint : mulu;
-        import core.stdc.stdlib : malloc;
+        import core.memory : pureMalloc;
         bool overflow;
         const nbytes = mulu(len, T.sizeof, overflow);
         if (overflow) assert(false, "multiplication overflowed");
-        T[] result = (cast(T*) malloc(nbytes))[0 .. len];
+        T[] result = (cast(T*) pureMalloc(nbytes))[0 .. len];
         static if (hasIndirections!T)
         {
             import core.memory : GC;
@@ -3145,15 +3145,15 @@ if (isRandomAccessRange!R && hasLength!R && hasSwappableElements!R &&
         {
             foreach (i; 0 .. length) collectException(destroy(xform1[i]));
         }
-        static void trustedFree(T[] p) @trusted
+        static void trustedFree()(T[] p) @trusted
         {
-            import core.stdc.stdlib : free;
+            import core.memory : pureFree;
             static if (hasIndirections!T)
             {
                 import core.memory : GC;
                 GC.removeRange(p.ptr);
             }
-            free(p.ptr);
+            pureFree(p.ptr);
         }
         trustedFree(xform1);
     }
@@ -3186,7 +3186,7 @@ if (isRandomAccessRange!R && hasLength!R && hasSwappableElements!R)
 }
 
 ///
-@safe unittest
+@safe pure unittest
 {
     import std.algorithm.iteration : map;
     import std.numeric : entropy;
@@ -3207,7 +3207,7 @@ if (isRandomAccessRange!R && hasLength!R && hasSwappableElements!R)
     assert(isSorted!("a > b")(map!(entropy)(arr)));
 }
 
-@safe unittest
+@safe pure unittest
 {
     import std.algorithm.iteration : map;
     import std.numeric : entropy;
@@ -3228,7 +3228,7 @@ if (isRandomAccessRange!R && hasLength!R && hasSwappableElements!R)
     assert(isSorted!("a < b")(map!(entropy)(arr)));
 }
 
-@safe unittest
+@safe pure unittest
 {
     // binary transform function
     string[] strings = [ "one", "two", "three" ];
@@ -3237,7 +3237,7 @@ if (isRandomAccessRange!R && hasLength!R && hasSwappableElements!R)
 }
 
 // https://issues.dlang.org/show_bug.cgi?id=4909
-@safe unittest
+@safe pure unittest
 {
     import std.typecons : Tuple;
     Tuple!(char)[] chars;
@@ -3245,7 +3245,7 @@ if (isRandomAccessRange!R && hasLength!R && hasSwappableElements!R)
 }
 
 // https://issues.dlang.org/show_bug.cgi?id=5924
-@safe unittest
+@safe pure unittest
 {
     import std.typecons : Tuple;
     Tuple!(char)[] chars;
@@ -3253,7 +3253,7 @@ if (isRandomAccessRange!R && hasLength!R && hasSwappableElements!R)
 }
 
 // https://issues.dlang.org/show_bug.cgi?id=13965
-@safe unittest
+@safe pure unittest
 {
     import std.typecons : Tuple;
     Tuple!(char)[] chars;
@@ -3261,7 +3261,7 @@ if (isRandomAccessRange!R && hasLength!R && hasSwappableElements!R)
 }
 
 // https://issues.dlang.org/show_bug.cgi?id=13965
-@safe unittest
+@safe pure unittest
 {
     import std.algorithm.iteration : map;
     import std.numeric : entropy;
diff --git a/libphobos/src/std/concurrency.d b/libphobos/src/std/concurrency.d
index a9830af61a2..fb383ae3f2e 100644
--- a/libphobos/src/std/concurrency.d
+++ b/libphobos/src/std/concurrency.d
@@ -2149,14 +2149,16 @@ private
 
                     if (msg.convertsTo!(Args))
                     {
-                        static if (is(ReturnType!(t) == bool))
+                        alias RT = ReturnType!(t);
+                        static if (is(RT == bool))
                         {
                             return msg.map(op);
                         }
                         else
                         {
                             msg.map(op);
-                            return true;
+                            static if (!is(immutable RT == immutable noreturn))
+                                return true;
                         }
                     }
                 }
@@ -2745,7 +2747,8 @@ auto ref initOnce(alias var)(lazy typeof(var) init, shared Mutex mutex)
             if (!atomicLoad!(MemoryOrder.raw)(flag))
             {
                 var = init;
-                atomicStore!(MemoryOrder.rel)(flag, true);
+                static if (!is(immutable typeof(var) == immutable noreturn))
+                    atomicStore!(MemoryOrder.rel)(flag, true);
             }
         }
     }
@@ -2827,3 +2830,26 @@ auto ref initOnce(alias var)(lazy typeof(var) init, Mutex mutex)
     immutable expected = Aggregate(42, [1, 2, 3, 4, 5]);
     assert(result1 == expected);
 }
+
+// Noreturn support
+@system unittest
+{
+    static noreturn foo(int) { throw new Exception(""); }
+
+    if (false) spawn(&foo, 1);
+    if (false) spawnLinked(&foo, 1);
+
+    if (false) receive(&foo);
+    if (false) receiveTimeout(Duration.init, &foo);
+
+    // Wrapped in __traits(compiles) to skip codegen which crashes dmd's backend
+    static assert(__traits(compiles, receiveOnly!noreturn()                 ));
+    static assert(__traits(compiles, send(Tid.init, noreturn.init)          ));
+    static assert(__traits(compiles, prioritySend(Tid.init, noreturn.init)  ));
+    static assert(__traits(compiles, yield(noreturn.init)                   ));
+
+    static assert(__traits(compiles, {
+        __gshared noreturn n;
+        initOnce!n(noreturn.init);
+    }));
+}
diff --git a/libphobos/src/std/container/dlist.d b/libphobos/src/std/container/dlist.d
index cc3e2e85dbc..32d56ecc733 100644
--- a/libphobos/src/std/container/dlist.d
+++ b/libphobos/src/std/container/dlist.d
@@ -196,6 +196,12 @@ struct DList(T)
 
         T _payload = T.init;
 
+        this (BaseNode _base, T _payload)
+        {
+            this._base = _base;
+            this._payload = _payload;
+        }
+
         inout(BaseNode)* asBaseNode() inout @trusted
         {
             return &_base;
diff --git a/libphobos/src/std/container/rbtree.d b/libphobos/src/std/container/rbtree.d
index f8e70fc0882..0b0a0b2f59f 100644
--- a/libphobos/src/std/container/rbtree.d
+++ b/libphobos/src/std/container/rbtree.d
@@ -887,7 +887,7 @@ if (is(typeof(binaryFun!less(T.init, T.init))))
      * Returns:
      *   true if node was added
      */
-    private bool _add(return Elem n)
+    private bool _add(return scope Elem n)
     {
         Node result;
         static if (!allowDuplicates)
diff --git a/libphobos/src/std/datetime/interval.d b/libphobos/src/std/datetime/interval.d
index 741088a72dc..ba2a21056c7 100644
--- a/libphobos/src/std/datetime/interval.d
+++ b/libphobos/src/std/datetime/interval.d
@@ -8349,7 +8349,7 @@ private:
     }
 
     {
-        SysTime stFunc(scope const SysTime st) { return cast(SysTime) st; }
+        SysTime stFunc(scope const SysTime st) { return SysTime.init; }
         auto interval = Interval!SysTime(SysTime(DateTime(2010, 7, 4, 12, 1, 7)),
                                          SysTime(DateTime(2012, 1, 7, 14, 0, 0)));
         auto ir = IntervalRange!(SysTime, Direction.fwd)(interval, &stFunc);
@@ -8794,7 +8794,7 @@ private:
     }
 
     {
-        SysTime stFunc(scope const SysTime st) { return cast(SysTime) st; }
+        SysTime stFunc(scope const SysTime st) { return SysTime.init; }
         auto posInfInterval = PosInfInterval!SysTime(SysTime(DateTime(2010, 7, 4, 12, 1, 7)));
         auto ir = PosInfIntervalRange!SysTime(posInfInterval, &stFunc);
     }
@@ -9076,7 +9076,7 @@ private:
     }
 
     {
-        SysTime stFunc(scope const SysTime st) { return cast(SysTime)(st); }
+        SysTime stFunc(scope const SysTime st) { return SysTime.init; }
         auto negInfInterval = NegInfInterval!SysTime(SysTime(DateTime(2012, 1, 7, 14, 0, 0)));
         auto ir = NegInfIntervalRange!(SysTime)(negInfInterval, &stFunc);
     }
diff --git a/libphobos/src/std/datetime/systime.d b/libphobos/src/std/datetime/systime.d
index 4da1281f98a..9b2a8443fdd 100644
--- a/libphobos/src/std/datetime/systime.d
+++ b/libphobos/src/std/datetime/systime.d
@@ -503,7 +503,7 @@ public:
                        given $(REF DateTime,std,datetime,date) is assumed to
                        be in the given time zone.
       +/
-    this(DateTime dateTime, immutable TimeZone tz = null) @safe nothrow
+    this(DateTime dateTime, return scope immutable TimeZone tz = null) return scope @safe nothrow
     {
         try
             this(dateTime, Duration.zero, tz);
@@ -554,7 +554,7 @@ public:
             $(REF DateTimeException,std,datetime,date) if `fracSecs` is negative or if it's
             greater than or equal to one second.
       +/
-    this(DateTime dateTime, Duration fracSecs, immutable TimeZone tz = null) @safe
+    this(DateTime dateTime, Duration fracSecs, return scope immutable TimeZone tz = null) return scope @safe
     {
         enforce(fracSecs >= Duration.zero, new DateTimeException("A SysTime cannot have negative fractional seconds."));
         enforce(fracSecs < seconds(1), new DateTimeException("Fractional seconds must be less than one second."));
@@ -611,7 +611,7 @@ public:
                    given $(REF Date,std,datetime,date) is assumed to be in the
                    given time zone.
       +/
-    this(Date date, immutable TimeZone tz = null) @safe nothrow
+    this(Date date, return scope immutable TimeZone tz = null) return scope @safe nothrow
     {
         _timezone = tz is null ? LocalTime() : tz;
 
@@ -664,7 +664,7 @@ public:
                       $(LREF SysTime). If null,
                       $(REF LocalTime,std,datetime,timezone) will be used.
       +/
-    this(long stdTime, immutable TimeZone tz = null) @safe pure nothrow
+    this(long stdTime, return scope immutable TimeZone tz = null) return scope @safe pure nothrow
     {
         _stdTime = stdTime;
         _timezone = tz is null ? LocalTime() : tz;
@@ -693,7 +693,7 @@ public:
 
         Returns: The `this` of this `SysTime`.
       +/
-    ref SysTime opAssign()(auto ref const(SysTime) rhs) return @safe pure nothrow scope
+    ref SysTime opAssign()(auto ref const(SysTime) rhs) return scope @safe pure nothrow
     {
         _stdTime = rhs._stdTime;
         _timezone = rhs._timezone;
@@ -710,6 +710,7 @@ public:
         st = other;
         assert(st == other);
 
+        version (none) // https://issues.dlang.org/show_bug.cgi?id=21175
         static void testScope(scope ref SysTime left, const scope SysTime right) @safe
         {
             left = right;
@@ -2184,7 +2185,7 @@ public:
         hours - adjust the time to this $(LREF SysTime)'s time zone before
         returning.
       +/
-    @property immutable(TimeZone) timezone() @safe const pure nothrow scope
+    @property immutable(TimeZone) timezone() @safe const pure nothrow return scope
     {
         return _timezone;
     }
@@ -2238,7 +2239,7 @@ public:
     /++
         Returns whether DST is in effect for this $(LREF SysTime).
       +/
-    @property bool dstInEffect() @safe const nothrow scope
+    @property bool dstInEffect() @safe const nothrow return scope
     {
         return _timezone.dstInEffect(_stdTime);
     }
@@ -2261,7 +2262,7 @@ public:
         Returns what the offset from UTC is for this $(LREF SysTime).
         It includes the DST offset in effect at that time (if any).
       +/
-    @property Duration utcOffset() @safe const nothrow scope
+    @property Duration utcOffset() @safe const nothrow return scope
     {
         return _timezone.utcOffsetAt(_stdTime);
     }
@@ -9586,13 +9587,13 @@ private:
 
         @property override bool hasDST() @safe const nothrow @nogc { return false; }
 
-        override bool dstInEffect(long stdTime) @safe const nothrow @nogc { return false; }
+        override bool dstInEffect(long stdTime) @safe const scope nothrow @nogc { return false; }
 
-        override long utcToTZ(long stdTime) @safe const nothrow @nogc { return 0; }
+        override long utcToTZ(long stdTime) @safe const scope nothrow @nogc { return 0; }
 
-        override long tzToUTC(long adjTime) @safe const nothrow @nogc { return 0; }
+        override long tzToUTC(long adjTime) @safe const scope nothrow @nogc { return 0; }
 
-        override Duration utcOffsetAt(long stdTime) @safe const nothrow @nogc { return Duration.zero; }
+        override Duration utcOffsetAt(long stdTime) @safe const scope nothrow @nogc { return Duration.zero; }
 
     private:
 
@@ -9628,7 +9629,7 @@ private:
         return _timezoneStorage is null ? InitTimeZone() : _timezoneStorage;
     }
 
-    pragma(inline, true) @property void _timezone(immutable TimeZone tz) @safe pure nothrow @nogc scope
+    pragma(inline, true) @property void _timezone(return scope immutable TimeZone tz) @safe pure nothrow @nogc scope
     {
         _timezoneStorage = tz;
     }
diff --git a/libphobos/src/std/datetime/timezone.d b/libphobos/src/std/datetime/timezone.d
index 052758097a9..a55411b02d5 100644
--- a/libphobos/src/std/datetime/timezone.d
+++ b/libphobos/src/std/datetime/timezone.d
@@ -100,7 +100,7 @@ public:
         However, on Windows, it may be the unabbreviated name (e.g. Pacific
         Standard Time). Regardless, it is not the same as name.
       +/
-    @property string stdName() @safe const nothrow
+    @property string stdName() @safe const scope nothrow
     {
         return _stdName;
     }
@@ -113,7 +113,7 @@ public:
         However, on Windows, it may be the unabbreviated name (e.g. Pacific
         Daylight Time). Regardless, it is not the same as name.
       +/
-    @property string dstName() @safe const nothrow
+    @property string dstName() @safe const scope nothrow
     {
         return _dstName;
     }
@@ -137,7 +137,7 @@ public:
             stdTime = The UTC time that needs to be checked for DST in this time
                       zone.
       +/
-    abstract bool dstInEffect(long stdTime) @safe const nothrow;
+    abstract bool dstInEffect(long stdTime) @safe const scope nothrow;
 
 
     /++
@@ -148,7 +148,7 @@ public:
             stdTime = The UTC time that needs to be adjusted to this time zone's
                       time.
       +/
-    abstract long utcToTZ(long stdTime) @safe const nothrow;
+    abstract long utcToTZ(long stdTime) @safe const scope nothrow;
 
 
     /++
@@ -159,7 +159,7 @@ public:
             adjTime = The time in this time zone that needs to be adjusted to
                       UTC time.
       +/
-    abstract long tzToUTC(long adjTime) @safe const nothrow;
+    abstract long tzToUTC(long adjTime) @safe const scope nothrow;
 
 
     /++
@@ -170,7 +170,7 @@ public:
             stdTime = The UTC time for which to get the offset from UTC for this
                       time zone.
       +/
-    Duration utcOffsetAt(long stdTime) @safe const nothrow
+    Duration utcOffsetAt(long stdTime) @safe const scope nothrow
     {
         return dur!"hnsecs"(utcToTZ(stdTime) - stdTime);
     }
@@ -580,7 +580,7 @@ public:
         dynamically rather than it being fixed like it would be with most time
         zones.
       +/
-    @property override string stdName() @trusted const nothrow
+    @property override string stdName() @trusted const scope nothrow
     {
         version (Posix)
         {
@@ -665,7 +665,7 @@ public:
         dynamically rather than it being fixed like it would be with most time
         zones.
       +/
-    @property override string dstName() @trusted const nothrow
+    @property override string dstName() @trusted const scope nothrow
     {
         version (Posix)
         {
@@ -809,7 +809,7 @@ public:
             stdTime = The UTC time that needs to be checked for DST in this time
                       zone.
       +/
-    override bool dstInEffect(long stdTime) @trusted const nothrow
+    override bool dstInEffect(long stdTime) @trusted const scope nothrow
     {
         import core.stdc.time : tm;
 
@@ -863,7 +863,7 @@ public:
         See_Also:
             `TimeZone.utcToTZ`
       +/
-    override long utcToTZ(long stdTime) @trusted const nothrow
+    override long utcToTZ(long stdTime) @trusted const scope nothrow
     {
         version (Solaris)
             return stdTime + convert!("seconds", "hnsecs")(tm_gmtoff(stdTime));
@@ -904,7 +904,7 @@ public:
             adjTime = The time in this time zone that needs to be adjusted to
                       UTC time.
       +/
-    override long tzToUTC(long adjTime) @trusted const nothrow
+    override long tzToUTC(long adjTime) @trusted const scope nothrow
     {
         version (Posix)
         {
@@ -1159,7 +1159,7 @@ public:
     /++
         Always returns false.
       +/
-    override bool dstInEffect(long stdTime) @safe const nothrow
+    override bool dstInEffect(long stdTime) @safe const scope nothrow
     {
         return false;
     }
@@ -1175,7 +1175,7 @@ public:
         See_Also:
             `TimeZone.utcToTZ`
       +/
-    override long utcToTZ(long stdTime) @safe const nothrow
+    override long utcToTZ(long stdTime) @safe const scope nothrow
     {
         return stdTime;
     }
@@ -1208,7 +1208,7 @@ public:
             adjTime = The time in this time zone that needs to be adjusted to
                       UTC time.
       +/
-    override long tzToUTC(long adjTime) @safe const nothrow
+    override long tzToUTC(long adjTime) @safe const scope nothrow
     {
         return adjTime;
     }
@@ -1238,7 +1238,7 @@ public:
             stdTime = The UTC time for which to get the offset from UTC for this
                       time zone.
       +/
-    override Duration utcOffsetAt(long stdTime) @safe const nothrow
+    override Duration utcOffsetAt(long stdTime) @safe const scope nothrow
     {
         return dur!"hnsecs"(0);
     }
@@ -1285,7 +1285,7 @@ public:
     /++
         Always returns false.
       +/
-    override bool dstInEffect(long stdTime) @safe const nothrow
+    override bool dstInEffect(long stdTime) @safe const scope nothrow
     {
         return false;
     }
@@ -1299,7 +1299,7 @@ public:
             stdTime = The UTC time that needs to be adjusted to this time zone's
                       time.
       +/
-    override long utcToTZ(long stdTime) @safe const nothrow
+    override long utcToTZ(long stdTime) @safe const scope nothrow
     {
         return stdTime + _utcOffset.total!"hnsecs";
     }
@@ -1326,7 +1326,7 @@ public:
             adjTime = The time in this time zone that needs to be adjusted to
                       UTC time.
       +/
-    override long tzToUTC(long adjTime) @safe const nothrow
+    override long tzToUTC(long adjTime) @safe const scope nothrow
     {
         return adjTime - _utcOffset.total!"hnsecs";
     }
@@ -1352,7 +1352,7 @@ public:
             stdTime = The UTC time for which to get the offset from UTC for this
                       time zone.
       +/
-    override Duration utcOffsetAt(long stdTime) @safe const nothrow
+    override Duration utcOffsetAt(long stdTime) @safe const scope nothrow
     {
         return _utcOffset;
     }
@@ -1919,7 +1919,7 @@ public:
             stdTime = The UTC time that needs to be checked for DST in this time
                       zone.
       +/
-    override bool dstInEffect(long stdTime) @safe const nothrow
+    override bool dstInEffect(long stdTime) @safe const scope nothrow
     {
         assert(!_transitions.empty);
 
@@ -1943,7 +1943,7 @@ public:
             stdTime = The UTC time that needs to be adjusted to this time zone's
                       time.
       +/
-    override long utcToTZ(long stdTime) @safe const nothrow
+    override long utcToTZ(long stdTime) @safe const scope nothrow
     {
         assert(!_transitions.empty);
 
@@ -1968,7 +1968,7 @@ public:
             adjTime = The time in this time zone that needs to be adjusted to
                       UTC time.
       +/
-    override long tzToUTC(long adjTime) @safe const nothrow
+    override long tzToUTC(long adjTime) @safe const scope nothrow
     {
         assert(!_transitions.empty, "UTC offset's not available");
 
@@ -2691,7 +2691,7 @@ private:
     }
 
 
-    int calculateLeapSeconds(long stdTime) @safe const pure nothrow
+    int calculateLeapSeconds(long stdTime) @safe const scope pure nothrow
     {
         if (_leapSeconds.empty)
             return 0;
@@ -2864,7 +2864,7 @@ version (StdDdoc)
             current dates but will still return true for `hasDST` because the
             time zone did at some point have DST.
           +/
-        @property override bool hasDST() @safe const nothrow;
+        @property override bool hasDST() @safe const scope nothrow;
 
 
         /++
@@ -2876,7 +2876,7 @@ version (StdDdoc)
                 stdTime = The UTC time that needs to be checked for DST in this
                           time zone.
           +/
-        override bool dstInEffect(long stdTime) @safe const nothrow;
+        override bool dstInEffect(long stdTime) @safe const scope nothrow;
 
 
         /++
@@ -2888,7 +2888,7 @@ version (StdDdoc)
                 stdTime = The UTC time that needs to be adjusted to this time
                           zone's time.
           +/
-        override long utcToTZ(long stdTime) @safe const nothrow;
+        override long utcToTZ(long stdTime) @safe const scope nothrow;
 
 
         /++
@@ -2900,7 +2900,7 @@ version (StdDdoc)
                 adjTime = The time in this time zone that needs to be adjusted
                           to UTC time.
           +/
-        override long tzToUTC(long adjTime) @safe const nothrow;
+        override long tzToUTC(long adjTime) @safe const scope nothrow;
 
 
         /++
@@ -2945,9 +2945,9 @@ version (StdDdoc)
         else
             alias TIME_ZONE_INFORMATION = void*;
 
-        static bool _dstInEffect(const TIME_ZONE_INFORMATION* tzInfo, long stdTime) nothrow;
-        static long _utcToTZ(const TIME_ZONE_INFORMATION* tzInfo, long stdTime, bool hasDST) nothrow;
-        static long _tzToUTC(const TIME_ZONE_INFORMATION* tzInfo, long adjTime, bool hasDST) nothrow;
+        static bool _dstInEffect(const scope TIME_ZONE_INFORMATION* tzInfo, long stdTime) nothrow;
+        static long _utcToTZ(const scope TIME_ZONE_INFORMATION* tzInfo, long stdTime, bool hasDST) nothrow;
+        static long _tzToUTC(const scope TIME_ZONE_INFORMATION* tzInfo, long adjTime, bool hasDST) nothrow;
 
         this() immutable pure
         {
@@ -2967,25 +2967,25 @@ else version (Windows)
 
     public:
 
-        @property override bool hasDST() @safe const nothrow
+        @property override bool hasDST() @safe const scope nothrow
         {
             return _tzInfo.DaylightDate.wMonth != 0;
         }
 
 
-        override bool dstInEffect(long stdTime) @safe const nothrow
+        override bool dstInEffect(long stdTime) @safe const scope nothrow
         {
             return _dstInEffect(&_tzInfo, stdTime);
         }
 
 
-        override long utcToTZ(long stdTime) @safe const nothrow
+        override long utcToTZ(long stdTime) @safe const scope nothrow
         {
             return _utcToTZ(&_tzInfo, stdTime, hasDST);
         }
 
 
-        override long tzToUTC(long adjTime) @safe const nothrow
+        override long tzToUTC(long adjTime) @safe const scope nothrow
         {
             return _tzToUTC(&_tzInfo, adjTime, hasDST);
         }
@@ -3071,7 +3071,7 @@ else version (Windows)
 
     private:
 
-        static bool _dstInEffect(const TIME_ZONE_INFORMATION* tzInfo, long stdTime) @trusted nothrow
+        static bool _dstInEffect(const scope TIME_ZONE_INFORMATION* tzInfo, long stdTime) @trusted nothrow
         {
             try
             {
@@ -3155,7 +3155,7 @@ else version (Windows)
         }
 
 
-        static long _utcToTZ(const TIME_ZONE_INFORMATION* tzInfo, long stdTime, bool hasDST) @safe nothrow
+        static long _utcToTZ(const scope TIME_ZONE_INFORMATION* tzInfo, long stdTime, bool hasDST) @safe nothrow
         {
             if (hasDST && WindowsTimeZone._dstInEffect(tzInfo, stdTime))
                 return stdTime - convert!("minutes", "hnsecs")(tzInfo.Bias + tzInfo.DaylightBias);
@@ -3164,7 +3164,7 @@ else version (Windows)
         }
 
 
-        static long _tzToUTC(const TIME_ZONE_INFORMATION* tzInfo, long adjTime, bool hasDST) @trusted nothrow
+        static long _tzToUTC(const scope TIME_ZONE_INFORMATION* tzInfo, long adjTime, bool hasDST) @trusted nothrow
         {
             if (hasDST)
             {
diff --git a/libphobos/src/std/file.d b/libphobos/src/std/file.d
index 1bfed64eae5..315e054cbab 100644
--- a/libphobos/src/std/file.d
+++ b/libphobos/src/std/file.d
@@ -1124,7 +1124,7 @@ version (Windows) private ulong makeUlong(DWORD dwLow, DWORD dwHigh) @safe pure
 }
 
 version (Posix) private extern (C) pragma(mangle, stat.mangleof)
-int trustedStat(const(FSChar)* namez, ref stat_t buf) @nogc nothrow @trusted;
+int trustedStat(scope const(FSChar)* namez, ref stat_t buf) @nogc nothrow @trusted;
 
 /**
 Get size of file `name` in bytes.
@@ -1928,7 +1928,7 @@ if (isConvertibleToString!R)
     assert(!f.exists);
 }
 
-private bool existsImpl(const(FSChar)* namez) @trusted nothrow @nogc
+private bool existsImpl(scope const(FSChar)* namez) @trusted nothrow @nogc
 {
     version (Windows)
     {
@@ -2010,7 +2010,7 @@ if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) &&
     version (Windows)
     {
         auto namez = name.tempCString!FSChar();
-        static auto trustedGetFileAttributesW(const(FSChar)* namez) @trusted
+        static auto trustedGetFileAttributesW(scope const(FSChar)* namez) @trusted
         {
             return GetFileAttributesW(namez);
         }
@@ -2220,7 +2220,7 @@ if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) &&
     version (Windows)
     {
         auto namez = name.tempCString!FSChar();
-        static auto trustedSetFileAttributesW(const(FSChar)* namez, uint dwFileAttributes) @trusted
+        static auto trustedSetFileAttributesW(scope const(FSChar)* namez, uint dwFileAttributes) @trusted
         {
             return SetFileAttributesW(namez, dwFileAttributes);
         }
@@ -2233,7 +2233,7 @@ if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) &&
     else version (Posix)
     {
         auto namez = name.tempCString!FSChar();
-        static auto trustedChmod(const(FSChar)* namez, mode_t mode) @trusted
+        static auto trustedChmod(scope const(FSChar)* namez, mode_t mode) @trusted
         {
             return chmod(namez, mode);
         }
@@ -2868,14 +2868,14 @@ if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) &&
 
     version (Windows)
     {
-        static auto trustedChdir(const(FSChar)* pathz) @trusted
+        static auto trustedChdir(scope const(FSChar)* pathz) @trusted
         {
             return SetCurrentDirectoryW(pathz);
         }
     }
     else version (Posix)
     {
-        static auto trustedChdir(const(FSChar)* pathz) @trusted
+        static auto trustedChdir(scope const(FSChar)* pathz) @trusted
         {
             return core.sys.posix.unistd.chdir(pathz) == 0;
         }
@@ -2939,7 +2939,7 @@ if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) &&
 
     version (Windows)
     {
-        static auto trustedCreateDirectoryW(const(FSChar)* pathz) @trusted
+        static auto trustedCreateDirectoryW(scope const(FSChar)* pathz) @trusted
         {
             return CreateDirectoryW(pathz, null);
         }
@@ -2953,7 +2953,7 @@ if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) &&
     {
         import std.conv : octal;
 
-        static auto trustedMkdir(const(FSChar)* pathz, mode_t mode) @trusted
+        static auto trustedMkdir(scope const(FSChar)* pathz, mode_t mode) @trusted
         {
             return core.sys.posix.sys.stat.mkdir(pathz, mode);
         }
@@ -3143,14 +3143,14 @@ if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) &&
 
     version (Windows)
     {
-        static auto trustedRmdir(const(FSChar)* pathz) @trusted
+        static auto trustedRmdir(scope const(FSChar)* pathz) @trusted
         {
             return RemoveDirectoryW(pathz);
         }
     }
     else version (Posix)
     {
-        static auto trustedRmdir(const(FSChar)* pathz) @trusted
+        static auto trustedRmdir(scope const(FSChar)* pathz) @trusted
         {
             return core.sys.posix.unistd.rmdir(pathz) == 0;
         }
@@ -3859,17 +3859,17 @@ else version (Windows)
             return _size;
         }
 
-        @property SysTime timeCreated() const pure nothrow scope
+        @property SysTime timeCreated() const pure nothrow return scope
         {
             return cast(SysTime)_timeCreated;
         }
 
-        @property SysTime timeLastAccessed() const pure nothrow scope
+        @property SysTime timeLastAccessed() const pure nothrow return scope
         {
             return cast(SysTime)_timeLastAccessed;
         }
 
-        @property SysTime timeLastModified() const pure nothrow scope
+        @property SysTime timeLastModified() const pure nothrow return scope
         {
             return cast(SysTime)_timeLastModified;
         }
diff --git a/libphobos/src/std/internal/cstring.d b/libphobos/src/std/internal/cstring.d
index a61ee81cc45..b21f58d602e 100644
--- a/libphobos/src/std/internal/cstring.d
+++ b/libphobos/src/std/internal/cstring.d
@@ -227,7 +227,7 @@ private struct TempCStringBuffer(To = char)
     @disable this(this);
     alias ptr this; /// implicitly covert to raw pointer
 
-    @property inout(To)* buffPtr() inout
+    @property inout(To)* buffPtr() return inout
     {
         return _ptr == useStack ? _buff.ptr : _ptr;
     }
diff --git a/libphobos/src/std/internal/math/biguintcore.d b/libphobos/src/std/internal/math/biguintcore.d
index 79446756fa6..6a93e0a16b0 100644
--- a/libphobos/src/std/internal/math/biguintcore.d
+++ b/libphobos/src/std/internal/math/biguintcore.d
@@ -879,7 +879,7 @@ public:
     }
 
     // return x / y
-    static BigUint divInt(T)(scope return BigUint x, T y_) pure nothrow @safe
+    static BigUint divInt(T)(return scope BigUint x, T y_) pure nothrow @safe
     if ( is(immutable T == immutable uint) )
     {
         uint y = y_;
@@ -942,7 +942,7 @@ public:
     }
 
     // return x / y
-    static BigUint div(scope return BigUint x, scope BigUint y) pure nothrow @safe
+    static BigUint div(return scope BigUint x, scope BigUint y) pure nothrow @safe
     {
         if (y.data.length > x.data.length)
             return BigUint(ZERO);
@@ -954,7 +954,7 @@ public:
     }
 
     // return x % y
-    static BigUint mod(scope return BigUint x, scope BigUint y) pure nothrow @safe
+    static BigUint mod(return scope BigUint x, scope BigUint y) pure nothrow @safe
     {
         if (y.data.length > x.data.length) return x;
         if (y.data.length == 1)
@@ -1020,7 +1020,7 @@ public:
      * exponentiation is used.
      * Memory allocation is minimized: at most one temporary BigUint is used.
      */
-    static BigUint pow(scope return BigUint x, ulong y) pure nothrow @safe
+    static BigUint pow(return scope BigUint x, ulong y) pure nothrow @safe
     {
         // Deal with the degenerate cases first.
         if (y == 0) return BigUint(ONE);
@@ -1259,7 +1259,7 @@ public:
 }
 
 // Remove leading zeros from x, to restore the BigUint invariant
-inout(BigDigit) [] removeLeadingZeros(scope return inout(BigDigit) [] x) pure nothrow @safe
+inout(BigDigit) [] removeLeadingZeros(return scope inout(BigDigit) [] x) pure nothrow @safe
 {
     size_t k = x.length;
     while (k>1 && x[k - 1]==0) --k;
@@ -1916,7 +1916,7 @@ pure @safe unittest
 // every 8 digits.
 // buff.length must be data.length*8 if separator is zero,
 // or data.length*9 if separator is non-zero. It will be completely filled.
-char [] biguintToHex(scope return char [] buff, const scope BigDigit [] data, char separator=0,
+char [] biguintToHex(return scope char [] buff, const scope BigDigit [] data, char separator=0,
         LetterCase letterCase = LetterCase.upper) pure nothrow @safe
 {
     int x=0;
diff --git a/libphobos/src/std/json.d b/libphobos/src/std/json.d
index af7aa383d8e..ea22d635766 100644
--- a/libphobos/src/std/json.d
+++ b/libphobos/src/std/json.d
@@ -159,7 +159,7 @@ struct JSONValue
         return store.str;
     }
     /// ditto
-    @property string str(return string v) pure nothrow @nogc @trusted return // TODO make @safe
+    @property string str(return scope string v) pure nothrow @nogc @trusted return // TODO make @safe
     {
         assign(v);
         return v;
@@ -282,7 +282,7 @@ struct JSONValue
         return store.object;
     }
     /// ditto
-    @property JSONValue[string] object(return JSONValue[string] v) pure nothrow @nogc @trusted // TODO make @safe
+    @property JSONValue[string] object(return scope JSONValue[string] v) pure nothrow @nogc @trusted // TODO make @safe
     {
         assign(v);
         return v;
@@ -321,14 +321,14 @@ struct JSONValue
        (*a)[0] = "world";  // segmentation fault
        ---
      */
-    @property ref inout(JSONValue[]) array() inout pure @system
+    @property ref inout(JSONValue[]) array() return scope inout pure @system
     {
         enforce!JSONException(type == JSONType.array,
                                 "JSONValue is not an array");
         return store.array;
     }
     /// ditto
-    @property JSONValue[] array(return JSONValue[] v) pure nothrow @nogc @trusted scope // TODO make @safe
+    @property JSONValue[] array(return scope JSONValue[] v) pure nothrow @nogc @trusted scope // TODO make @safe
     {
         assign(v);
         return v;
@@ -635,7 +635,7 @@ struct JSONValue
      * Hash syntax for json objects.
      * Throws: `JSONException` if `type` is not `JSONType.object`.
      */
-    ref inout(JSONValue) opIndex(return string k) inout pure @safe
+    ref inout(JSONValue) opIndex(return scope string k) inout pure @safe
     {
         auto o = this.objectNoRef;
         return *enforce!JSONException(k in o,
diff --git a/libphobos/src/std/net/isemail.d b/libphobos/src/std/net/isemail.d
index f2a8ff3025d..12a29fe44c9 100644
--- a/libphobos/src/std/net/isemail.d
+++ b/libphobos/src/std/net/isemail.d
@@ -1893,7 +1893,7 @@ Note that only the first item of "matchAll" was ever used in practice
 so we can return `const(Char)[]` instead of `const(Char)[][]` using a
 zero-length string to indicate no match.
 +/
-const(Char)[] matchIPSuffix(Char)(return const(Char)[] s) @nogc nothrow pure @safe
+const(Char)[] matchIPSuffix(Char)(return scope const(Char)[] s) @nogc nothrow pure @safe
 {
     size_t end = s.length;
     if (end < 7) return null;
diff --git a/libphobos/src/std/process.d b/libphobos/src/std/process.d
index 98c5b946748..958f606ff52 100644
--- a/libphobos/src/std/process.d
+++ b/libphobos/src/std/process.d
@@ -276,7 +276,7 @@ static:
     multi-threaded programs. See e.g.
     $(LINK2 https://www.gnu.org/software/libc/manual/html_node/Environment-Access.html#Environment-Access, glibc).
     */
-    inout(char)[] opIndexAssign(return inout char[] value, scope const(char)[] name) @trusted
+    inout(char)[] opIndexAssign(return scope inout char[] value, scope const(char)[] name) @trusted
     {
         version (Posix)
         {
@@ -4385,6 +4385,7 @@ else version (Posix)
 
     void browse(scope const(char)[] url) nothrow @nogc @safe
     {
+        const buffer = url.tempCString(); // Retain buffer until end of scope
         const(char)*[3] args;
 
         // Trusted because it's called with a zero-terminated literal
@@ -4408,7 +4409,6 @@ else version (Posix)
             }
         }
 
-        const buffer = url.tempCString(); // Retain buffer until end of scope
         args[1] = buffer;
         args[2] = null;
 
diff --git a/libphobos/src/std/random.d b/libphobos/src/std/random.d
index a3483561134..106e51ceedb 100644
--- a/libphobos/src/std/random.d
+++ b/libphobos/src/std/random.d
@@ -166,12 +166,16 @@ version (D_InlineAsm_X86_64) version = InlineAsm_X86_Any;
     assert(10.iota.randomSample(3, rnd2).equal([7, 8, 9]));
 
     // Cover all elements in an array in random order
-    version (X86_64) // https://issues.dlang.org/show_bug.cgi?id=15147
-    assert(10.iota.randomCover(rnd2).equal([7, 4, 2, 0, 1, 6, 8, 3, 9, 5]));
+    version (D_LP64) // https://issues.dlang.org/show_bug.cgi?id=15147
+        assert(10.iota.randomCover(rnd2).equal([7, 4, 2, 0, 1, 6, 8, 3, 9, 5]));
+    else
+        assert(10.iota.randomCover(rnd2).equal([4, 8, 7, 3, 5, 9, 2, 6, 0, 1]));
 
     // Shuffle an array
-    version (X86_64) // https://issues.dlang.org/show_bug.cgi?id=15147
-    assert([0, 1, 2, 4, 5].randomShuffle(rnd2).equal([2, 0, 4, 5, 1]));
+    version (D_LP64) // https://issues.dlang.org/show_bug.cgi?id=15147
+        assert([0, 1, 2, 4, 5].randomShuffle(rnd2).equal([2, 0, 4, 5, 1]));
+    else
+        assert([0, 1, 2, 4, 5].randomShuffle(rnd2).equal([4, 2, 5, 0, 1]));
 }
 
 version (StdUnittest)
diff --git a/libphobos/src/std/stdio.d b/libphobos/src/std/stdio.d
index d3097d548ce..f30ea80ae44 100644
--- a/libphobos/src/std/stdio.d
+++ b/libphobos/src/std/stdio.d
@@ -4650,7 +4650,7 @@ if ((isInputRange!R1 && isSomeChar!(ElementEncodingType!R1) || isSomeString!R1)
     auto namez = name.tempCString!FSChar();
     auto modez = mode.tempCString!FSChar();
 
-    static _fopenImpl(const(FSChar)* namez, const(FSChar)* modez) @trusted nothrow @nogc
+    static _fopenImpl(scope const(FSChar)* namez, scope const(FSChar)* modez) @trusted nothrow @nogc
     {
         version (Windows)
         {
diff --git a/libphobos/src/std/typecons.d b/libphobos/src/std/typecons.d
index db0e3da304c..6dee863521d 100644
--- a/libphobos/src/std/typecons.d
+++ b/libphobos/src/std/typecons.d
@@ -2239,7 +2239,7 @@ if (is(T == class) || is(T == interface) || isAssociativeArray!T)
         U stripped;
     }
 
-    void opAssign(T another) pure nothrow @nogc
+    void opAssign(return scope T another) pure nothrow @nogc
     {
         // If `T` defines `opCast` we must infer the safety
         static if (hasMember!(T, "opCast"))
@@ -2271,7 +2271,7 @@ if (is(T == class) || is(T == interface) || isAssociativeArray!T)
         opAssign(initializer);
     }
 
-    @property inout(T) get() @trusted pure nothrow @nogc inout
+    @property inout(T) get() @trusted pure nothrow @nogc return scope inout
     {
         return original;
     }
@@ -2792,6 +2792,15 @@ struct Nullable(T)
         }
     }
 
+    this (ref return scope inout Nullable!T rhs) inout
+    {
+        _isNull = rhs._isNull;
+        if (!_isNull)
+            _value.payload = rhs._value.payload;
+        else
+            _value = DontCallDestructorT.init;
+    }
+
     /**
      * If they are both null, then they are equal. If one is null and the other
      * is not, then they are not equal. If they are both non-null, then they are
@@ -3284,11 +3293,11 @@ auto nullable(T)(T t)
     static struct S2 //inspired from 9404
     {
         Nullable!int ni;
-        this(S2 other)
+        this(ref S2 other)
         {
             ni = other.ni;
         }
-        void opAssign(S2 other)
+        void opAssign(ref S2 other)
         {
             ni = other.ni;
         }
@@ -9566,3 +9575,21 @@ unittest
     assert((a ^ true) == Ternary.no);
     assert((a ^ false) == Ternary.yes);
 }
+
+// https://issues.dlang.org/show_bug.cgi?id=22511
+@safe unittest
+{
+    static struct S
+    {
+        int b;
+        @disable this(this);
+        this (ref return scope inout S rhs) inout
+        {
+            this.b = rhs.b + 1;
+        }
+    }
+
+    Nullable!S s1 = S(1);
+    Nullable!S s2 = s1;
+    assert(s2.get().b > s1.get().b);
+}
diff --git a/libphobos/src/std/uni/package.d b/libphobos/src/std/uni/package.d
index 45b7207c1f1..a27cbea177b 100644
--- a/libphobos/src/std/uni/package.d
+++ b/libphobos/src/std/uni/package.d
@@ -1987,8 +1987,8 @@ pure:
     {
         return this[0] == val[0] && this[1] == val[1];
     }
-    @property ref inout(uint) a() inout { return _tuple[0]; }
-    @property ref inout(uint) b() inout { return _tuple[1]; }
+    @property ref inout(uint) a() return inout { return _tuple[0]; }
+    @property ref inout(uint) b() return inout { return _tuple[1]; }
 }
 
 /**
diff --git a/libphobos/src/std/utf.d b/libphobos/src/std/utf.d
index be60e7a8f3a..866ec48cbdc 100644
--- a/libphobos/src/std/utf.d
+++ b/libphobos/src/std/utf.d
@@ -4315,12 +4315,12 @@ if (isSomeChar!C)
             {
                 enum Empty = uint.max;  // range is empty or just constructed
 
-                this(return R r)
+                this(return scope R r)
                 {
                     this.r = r;
                 }
 
-                this(return R r, uint buff)
+                this(return scope R r, uint buff)
                 {
                     this.r = r;
                     this.buff = buff;
@@ -4328,7 +4328,7 @@ if (isSomeChar!C)
 
                 static if (isBidirectionalRange!R)
                 {
-                    this(return R r, uint frontBuff, uint backBuff)
+                    this(return scope R r, uint frontBuff, uint backBuff)
                     {
                         this.r = r;
                         this.buff = frontBuff;
@@ -4436,12 +4436,12 @@ if (isSomeChar!C)
         {
             static struct Result
             {
-                this(return R r)
+                this(return scope R r)
                 {
                     this.r = r;
                 }
 
-                this(return R r, ushort pos, ushort fill, C[4 / C.sizeof] buf)
+                this(return scope R r, ushort pos, ushort fill, C[4 / C.sizeof] buf)
                 {
                     this.r = r;
                     this.pos = pos;
@@ -4451,7 +4451,7 @@ if (isSomeChar!C)
 
                 static if (isBidirectionalRange!R)
                 {
-                    this(return R r, ushort frontPos, ushort frontFill,
+                    this(return scope R r, ushort frontPos, ushort frontFill,
                          ushort backPos, ushort backFill, C[4 / C.sizeof] buf)
                     {
                         this.r = r;
diff --git a/libphobos/testsuite/libphobos.config/config.exp b/libphobos/testsuite/libphobos.config/config.exp
index e8f4d943ff3..544caa204b3 100644
--- a/libphobos/testsuite/libphobos.config/config.exp
+++ b/libphobos/testsuite/libphobos.config/config.exp
@@ -22,6 +22,7 @@ set dg-output-text [list]
 set config_test_list [list \
     { test19433 "--DRT-dont-eat-me" 0 } \
     { test20459 "foo bar -- --DRT-gcopts=profile:1" 0 } \
+    { test22523 "-- --DRT-testmode=run-main" 0 } \
 ]
 
 # Initialize dg.
diff --git a/libphobos/testsuite/libphobos.config/test22523.d b/libphobos/testsuite/libphobos.config/test22523.d
new file mode 100644
index 00000000000..f3086963f2e
--- /dev/null
+++ b/libphobos/testsuite/libphobos.config/test22523.d
@@ -0,0 +1,11 @@
+// https://issues.dlang.org/show_bug.cgi?id=22523
+
+import core.stdc.stdio;
+
+int main()
+{
+    puts("Executed main although it should be skipped!");
+    return 1;
+}
+
+unittest {}
