Hello community,

here is the log from the commit of package dmd for openSUSE:Factory checked in 
at 2019-04-14 12:23:33
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/dmd (Old)
 and      /work/SRC/openSUSE:Factory/.dmd.new.27019 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "dmd"

Sun Apr 14 12:23:33 2019 rev:25 rq:693900 version:2.085.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/dmd/dmd.changes  2019-03-18 10:43:47.735117836 
+0100
+++ /work/SRC/openSUSE:Factory/.dmd.new.27019/dmd.changes       2019-04-14 
12:23:35.131840046 +0200
@@ -1,0 +2,33 @@
+Sat Apr 13 10:01:13 UTC 2019 - Matthias Eliasson <[email protected]>
+
+- Update to version 2.085.1
+  - DMD Compiler regressions:
+    * DMD generates wrong code for some circular dependencies
+    * D compiler fails to resolve circular module dependency when modules are 
compiled separately
+    * D compiler fails to resolve circular module dependency when modules are 
compiled together
+    * ICE on null default value for struct parameter in constructor
+    * DMD 2.085 changes to gsroa make DCD crashing
+    * Regression: wrong order of linker arguments, again: -L-l before 
-L--start-group
+    * if (auto x) {} isn't properly rejected
+    * DMD fails to compile some circular dependencies spiced with is (T == 
super) condition
+    * [Reg v2.070.2] DMD fails with some circular module refs with 
Template/Mixin instances
+  - DMD Compiler bugs:
+    * wrong codegen for destructor call of unnamed struct instance on 64 bit 
environments
+    * case of undetected circular reference in function parameter
+    * ICE with multiple mixin templates containing conflicting ctor 
declarations
+    * Segfault when types are used in array literals
+    * DMD crash due to circular reference in function return type
+    * -checkaction=context not working with attributes
+    * [2.085.0-beta.2] Obj-C wrong code overloading selectors and extern(D)
+    * case of segfault due to undetected forward reference
+    * Compiler crash
+    * crash on invalid initializer at CTFE
+    * ICE on invalid code
+  - Phobos regressions:
+    * VariantN has unittests that are compiled into user modules
+  - Phobos bugs:
+    * std.algorithm.searching.findAmong doesn't save like it should
+  - Druntime bugs:
+    * wrong time values in GC.profileStats
+
+-------------------------------------------------------------------

Old:
----
  dmd-2.085.0.tar.gz
  druntime-2.085.0.tar.gz
  phobos-2.085.0.tar.gz

New:
----
  dmd-2.085.1.tar.gz
  druntime-2.085.1.tar.gz
  phobos-2.085.1.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ dmd.spec ++++++
--- /var/tmp/diff_new_pack.oG9woX/_old  2019-04-14 12:23:36.495841317 +0200
+++ /var/tmp/diff_new_pack.oG9woX/_new  2019-04-14 12:23:36.519841339 +0200
@@ -20,7 +20,7 @@
 %define sover  0_85
 %define auto_bootstrap 1
 Name:           dmd
-Version:        2.085.0
+Version:        2.085.1
 Release:        0
 Summary:        D Programming Language 2.0
 License:        BSL-1.0

++++++ dmd-2.085.0.tar.gz -> dmd-2.085.1.tar.gz ++++++
++++ 1772 lines of diff (skipped)

++++++ druntime-2.085.0.tar.gz -> druntime-2.085.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/druntime-2.085.0/.circleci/config.yml 
new/druntime-2.085.1/.circleci/config.yml
--- old/druntime-2.085.0/.circleci/config.yml   2019-02-15 20:09:43.000000000 
+0100
+++ new/druntime-2.085.1/.circleci/config.yml   2019-03-28 04:39:36.000000000 
+0100
@@ -3,8 +3,8 @@
   build:
     working_directory: ~/druntime
     docker:
-      - image: circleci/node:4.8.2
-    parallelism: 2
+      - image: circleci/buildpack-deps:18.04
+    parallelism: 1
     steps:
       - checkout
       - run:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/druntime-2.085.0/.circleci/run.sh 
new/druntime-2.085.1/.circleci/run.sh
--- old/druntime-2.085.0/.circleci/run.sh       2019-02-15 20:09:43.000000000 
+0100
+++ new/druntime-2.085.1/.circleci/run.sh       2019-03-28 04:39:36.000000000 
+0100
@@ -10,7 +10,7 @@
 
 case $CIRCLE_NODE_INDEX in
     0) MODEL=64 ;;
-    1) MODEL=32 ;;
+    1) MODEL=32 ;; # broken - https://issues.dlang.org/show_bug.cgi?id=19116
 esac
 
 download() {
@@ -98,8 +98,7 @@
     # load environment for bootstrap compiler
     source "$(CURL_USER_AGENT=\"$CURL_USER_AGENT\" bash ~/dlang/install.sh 
dmd-$HOST_DMD_VER --activate)"
 
-    # build dmd and druntime (in debug and release)
-    make -j$N -C ../dmd/src -f posix.mak MODEL=$MODEL HOST_DMD=$DMD 
BUILD="debug" all
+    # build dmd (release) and druntime (debug)
     make -j$N -C ../dmd/src -f posix.mak MODEL=$MODEL HOST_DMD=$DMD 
BUILD="release" all
     TEST_COVERAGE="1" make -j$N -C . -f posix.mak MODEL=$MODEL unittest-debug
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/druntime-2.085.0/changelog/core-memory-gc-profile-stats.dd 
new/druntime-2.085.1/changelog/core-memory-gc-profile-stats.dd
--- old/druntime-2.085.0/changelog/core-memory-gc-profile-stats.dd      
2019-02-15 20:09:43.000000000 +0100
+++ new/druntime-2.085.1/changelog/core-memory-gc-profile-stats.dd      
1970-01-01 01:00:00.000000000 +0100
@@ -1,4 +0,0 @@
-Added `GC.profileStats()` to `core.memory`
-
-Allows access to current GC profiling information.
-See $(REF GC.ProfileStats, core,memory) for a list of profile stats.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/druntime-2.085.0/changelog/cpp_new.dd 
new/druntime-2.085.1/changelog/cpp_new.dd
--- old/druntime-2.085.0/changelog/cpp_new.dd   2019-02-15 20:09:43.000000000 
+0100
+++ new/druntime-2.085.1/changelog/cpp_new.dd   1970-01-01 01:00:00.000000000 
+0100
@@ -1,4 +0,0 @@
-Added `core.stdcpp.new_`
-
-Added `core.stdcpp.new_`, which exposes interfaces for C++ global new/delete 
operators.
-This allows D programs to conveniently allocate from the C++ heap, which is 
useful when sharing memory between languages.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/druntime-2.085.0/changelog/cpu_count.dd 
new/druntime-2.085.1/changelog/cpu_count.dd
--- old/druntime-2.085.0/changelog/cpu_count.dd 2019-02-15 20:09:43.000000000 
+0100
+++ new/druntime-2.085.1/changelog/cpu_count.dd 1970-01-01 01:00:00.000000000 
+0100
@@ -1,3 +0,0 @@
-Added `core.sys.linux.sched.CPU_COUNT`.
-
-Added `core.sys.linux.sched.CPU_COUNT`, which returns the number of CPUs in 
set.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/druntime-2.085.0/changelog/cpu_isset.dd 
new/druntime-2.085.1/changelog/cpu_isset.dd
--- old/druntime-2.085.0/changelog/cpu_isset.dd 2019-02-15 20:09:43.000000000 
+0100
+++ new/druntime-2.085.1/changelog/cpu_isset.dd 1970-01-01 01:00:00.000000000 
+0100
@@ -1,3 +0,0 @@
-Added `core.sys.linux.sched.CPU_ISSET`.
-
-Added `core.sys.linux.sched.CPU_ISSET`, which tests to see if cpu is a member 
of set.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/druntime-2.085.0/changelog/emplace.dd 
new/druntime-2.085.1/changelog/emplace.dd
--- old/druntime-2.085.0/changelog/emplace.dd   2019-02-15 20:09:43.000000000 
+0100
+++ new/druntime-2.085.1/changelog/emplace.dd   1970-01-01 01:00:00.000000000 
+0100
@@ -1,4 +0,0 @@
-Moved `std.conv.emplace`, `std.algorithm.mutation.move`, 
`std.algorithm.mutation.moveEmplace`, and `std.functional.forward` to 
core/lifetime.d
-
-`emplace` is the counterpart to `destroy`, so it has been moved to also live 
in druntime (core/lifetime.d) where it is accessible by projects that use a 
shallow runtime library stack.
-`move`, `moveEmplace`, and `forward` are related low-level construction 
machinery which also belong in `core.lifetime`.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/druntime-2.085.0/changelog/gc_cleanup.dd 
new/druntime-2.085.1/changelog/gc_cleanup.dd
--- old/druntime-2.085.0/changelog/gc_cleanup.dd        2019-02-15 
20:09:43.000000000 +0100
+++ new/druntime-2.085.1/changelog/gc_cleanup.dd        1970-01-01 
01:00:00.000000000 +0100
@@ -1,26 +0,0 @@
-GC cleanup can now be configured as a DRT GC option
-
-The default cleanup method for the GC is to unconditionally run a
-collection before runtime termination to finalize objects
-that are still alive and hold resources that affect system state outside
-the current process. This combines the worst of possible alternatives:
-it can cause a considerable delay and does not guarantee finalization
-of all objects as roots might still exist.
-
-The cleanup behaviour can now be configured by a DRT option to the
-$(LINK2 $(ROOT_DIR)spec/garbage.html, GC configuration),
-e.g. by passing `--DRT-gcopt=cleanup:none` on the command
-line. Three options are provided:
-
-$(UL
-  $(LI collect: run a collection (the default for backward compatibility))
-  $(LI none: do nothing)
-  $(LI finalize: all live objects are finalized unconditionally)
-)
-
-As usual, you can also embed the configuration into the application by
-redefining `rt_options`, e.g.
-
--------
-extern(C) __gshared string[] rt_options = [ "gcopt=cleanup:none" ];
--------
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/druntime-2.085.0/changelog/gc_precise.dd 
new/druntime-2.085.1/changelog/gc_precise.dd
--- old/druntime-2.085.0/changelog/gc_precise.dd        2019-02-15 
20:09:43.000000000 +0100
+++ new/druntime-2.085.1/changelog/gc_precise.dd        1970-01-01 
01:00:00.000000000 +0100
@@ -1,8 +0,0 @@
-A garbage collector with precise heap scanning can now be selected
-
-Precise heap scanning can now be enabled by a DRT option to the
-$(LINK2 $(ROOT_DIR)spec/garbage.html, GC configuration),
-e.g. by passing `--DRT-gcopt=gc:precise` on the command
-line or by redefining `rt_options`. See the
-$(LINK2 $(ROOT_DIR)spec/garbage.html#precise_gc, documentation)
-for details.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/druntime-2.085.0/changelog/gc_realloc.dd 
new/druntime-2.085.1/changelog/gc_realloc.dd
--- old/druntime-2.085.0/changelog/gc_realloc.dd        2019-02-15 
20:09:43.000000000 +0100
+++ new/druntime-2.085.1/changelog/gc_realloc.dd        1970-01-01 
01:00:00.000000000 +0100
@@ -1,18 +0,0 @@
-GC.realloc is now more consistent and robust
-
-The specification of $(REF GC.realloc, core, memory) has changed slightly:
-
-$(UL
- $(LI `GC.realloc` now returns `null` for failure. (It used to return the 
original pointer but
-   that is is not a good indication of failure as it might also be returned on 
success. It can
-   lead to overwriting memory if an enlargement was requested.))
- $(LI as with `GC.free`, the caller has to ensure that there are no other live 
pointers to the
-   memory passed to `GC.realloc` (This used to be required only when passing a 
new size `0`).)
- $(LI as a consequence the GC is allowed to free the memory immediately (the 
previous
-   implementation did this for objects larger than 4kB when shrinking).)
- $(LI block attribute bits on the existing block are only set if it is reused 
(the previous
-   implementation didn't set bits if it reused a small block).)
-)
-
-The implementation now properly verifies that pointers are actually base 
pointers to allocated
-GC memory (passing other pointers could have crashed immediately or corrupt 
the GC).
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/druntime-2.085.0/changelog/gc_registry.dd 
new/druntime-2.085.1/changelog/gc_registry.dd
--- old/druntime-2.085.0/changelog/gc_registry.dd       2019-02-15 
20:09:43.000000000 +0100
+++ new/druntime-2.085.1/changelog/gc_registry.dd       1970-01-01 
01:00:00.000000000 +0100
@@ -1,7 +0,0 @@
-User supplied garbage collectors can now be linked with the runtime
-
-A GC registry has been implemented that allows to add
-garbage collector implementations by just linking them into
-the binary.  See the
-$(LINK2 $(ROOT_DIR)spec/garbage.html#gc_registry, documentation)
-for details.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/druntime-2.085.0/changelog/std_allocator.dd 
new/druntime-2.085.1/changelog/std_allocator.dd
--- old/druntime-2.085.0/changelog/std_allocator.dd     2019-02-15 
20:09:43.000000000 +0100
+++ new/druntime-2.085.1/changelog/std_allocator.dd     1970-01-01 
01:00:00.000000000 +0100
@@ -1,4 +0,0 @@
-Added `core.stdcpp.allocator`
-
-Added `core.stdcpp.allocator`, which exposes the C++ `std::allocator<T>` class.
-This is a required foundation for any of the allocating STL container types.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/druntime-2.085.0/changelog/zero_init.dd 
new/druntime-2.085.1/changelog/zero_init.dd
--- old/druntime-2.085.0/changelog/zero_init.dd 2019-02-15 20:09:43.000000000 
+0100
+++ new/druntime-2.085.1/changelog/zero_init.dd 1970-01-01 01:00:00.000000000 
+0100
@@ -1,3 +0,0 @@
-`char`/`wchar` fields in most D runtime (`core.*` and `rt.*`) structs are now 
zero-initialized
-
-Fields that are single `char`/wchar` or fixed-length arrays of such are now 
initialized to all zero bits instead of all one bits for most structs in the D 
runtime (`core.*` and `rt.*` modules). This simplifies initialization and 
removes the need to store init data when it makes the entire struct 
zero-initialized. Most affected structs are used for interoperability with C 
APIs.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/druntime-2.085.0/src/core/internal/dassert.d 
new/druntime-2.085.1/src/core/internal/dassert.d
--- old/druntime-2.085.0/src/core/internal/dassert.d    2019-02-15 
20:09:43.000000000 +0100
+++ new/druntime-2.085.1/src/core/internal/dassert.d    2019-03-28 
04:39:36.000000000 +0100
@@ -37,7 +37,7 @@
 Minimalistic formatting for use in _d_assert_fail to keep the compilation
 overhead small and avoid the use of Phobos.
 */
-auto miniFormat(V)(auto ref V v)
+auto miniFormat(V)(V v)
 {
     import core.stdc.stdio : sprintf;
     import core.stdc.string : strlen;
@@ -45,14 +45,14 @@
     {
         enum printfFormat = getPrintfFormat!V;
         char[20] val;
-        sprintf(val.ptr, printfFormat, v);
-        return val.idup[0 .. strlen(val.ptr)];
+        const len = sprintf(&val[0], printfFormat, v);
+        return val.idup[0 .. len];
     }
     else static if (__traits(isFloating, V))
     {
         char[60] val;
-        sprintf(val.ptr, "%g", v);
-        return val.idup[0 .. strlen(val.ptr)];
+        const len = sprintf(&val[0], "%g", v);
+        return val.idup[0 .. len];
     }
     else static if (__traits(compiles, { string s = V.init.toString(); }))
     {
@@ -145,3 +145,26 @@
     }
 }
 
+private auto assumeFakeAttributes(T)(T t) @trusted
+{
+    import core.internal.traits : Parameters, ReturnType;
+    alias RT = ReturnType!T;
+    alias P = Parameters!T;
+    alias type = RT function(P) nothrow @nogc @safe pure;
+    return cast(type) t;
+}
+
+auto miniFormatFakeAttributes(T)(T t)
+{
+    alias miniT = miniFormat!T;
+    return assumeFakeAttributes(&miniT)(t);
+}
+
+auto pureAlloc(size_t t)
+{
+    static auto alloc(size_t len)
+    {
+        return new ubyte[len];
+    }
+    return assumeFakeAttributes(&alloc)(t);
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/druntime-2.085.0/src/core/internal/traits.d 
new/druntime-2.085.1/src/core/internal/traits.d
--- old/druntime-2.085.0/src/core/internal/traits.d     2019-02-15 
20:09:43.000000000 +0100
+++ new/druntime-2.085.1/src/core/internal/traits.d     2019-03-28 
04:39:36.000000000 +0100
@@ -334,3 +334,217 @@
     static assert({ cast(void) dg(); return true; }());
     cast(void) dg();
 }
+
+// std.traits.FunctionTypeOf
+/*
+Get the function type from a callable object `func`.
+
+Using builtin `typeof` on a property function yields the types of the
+property value, not of the property function itself.  Still,
+`FunctionTypeOf` is able to obtain function types of properties.
+
+Note:
+Do not confuse function types with function pointer types; function types are
+usually used for compile-time reflection purposes.
+ */
+template FunctionTypeOf(func...)
+if (func.length == 1 /*&& isCallable!func*/)
+{
+    static if (is(typeof(& func[0]) Fsym : Fsym*) && is(Fsym == function) || 
is(typeof(& func[0]) Fsym == delegate))
+    {
+        alias FunctionTypeOf = Fsym; // HIT: (nested) function symbol
+    }
+    else static if (is(typeof(& func[0].opCall) Fobj == delegate))
+    {
+        alias FunctionTypeOf = Fobj; // HIT: callable object
+    }
+    else static if (is(typeof(& func[0].opCall) Ftyp : Ftyp*) && is(Ftyp == 
function))
+    {
+        alias FunctionTypeOf = Ftyp; // HIT: callable type
+    }
+    else static if (is(func[0] T) || is(typeof(func[0]) T))
+    {
+        static if (is(T == function))
+            alias FunctionTypeOf = T;    // HIT: function
+        else static if (is(T Fptr : Fptr*) && is(Fptr == function))
+            alias FunctionTypeOf = Fptr; // HIT: function pointer
+        else static if (is(T Fdlg == delegate))
+            alias FunctionTypeOf = Fdlg; // HIT: delegate
+        else
+            static assert(0);
+    }
+    else
+        static assert(0);
+}
+
+@safe unittest
+{
+    class C
+    {
+        int value() @property { return 0; }
+    }
+    static assert(is( typeof(C.value) == int ));
+    static assert(is( FunctionTypeOf!(C.value) == function ));
+}
+
+@system unittest
+{
+    int test(int a);
+    int propGet() @property;
+    int propSet(int a) @property;
+    int function(int) test_fp;
+    int delegate(int) test_dg;
+    static assert(is( typeof(test) == FunctionTypeOf!(typeof(test)) ));
+    static assert(is( typeof(test) == FunctionTypeOf!test ));
+    static assert(is( typeof(test) == FunctionTypeOf!test_fp ));
+    static assert(is( typeof(test) == FunctionTypeOf!test_dg ));
+    alias int GetterType() @property;
+    alias int SetterType(int) @property;
+    static assert(is( FunctionTypeOf!propGet == GetterType ));
+    static assert(is( FunctionTypeOf!propSet == SetterType ));
+
+    interface Prop { int prop() @property; }
+    Prop prop;
+    static assert(is( FunctionTypeOf!(Prop.prop) == GetterType ));
+    static assert(is( FunctionTypeOf!(prop.prop) == GetterType ));
+
+    class Callable { int opCall(int) { return 0; } }
+    auto call = new Callable;
+    static assert(is( FunctionTypeOf!call == typeof(test) ));
+
+    struct StaticCallable { static int opCall(int) { return 0; } }
+    StaticCallable stcall_val;
+    StaticCallable* stcall_ptr;
+    static assert(is( FunctionTypeOf!stcall_val == typeof(test) ));
+    static assert(is( FunctionTypeOf!stcall_ptr == typeof(test) ));
+
+    interface Overloads
+    {
+        void test(string);
+        real test(real);
+        int  test(int);
+        int  test() @property;
+    }
+    alias ov = __traits(getVirtualFunctions, Overloads, "test");
+    alias F_ov0 = FunctionTypeOf!(ov[0]);
+    alias F_ov1 = FunctionTypeOf!(ov[1]);
+    alias F_ov2 = FunctionTypeOf!(ov[2]);
+    alias F_ov3 = FunctionTypeOf!(ov[3]);
+    static assert(is(F_ov0* == void function(string)));
+    static assert(is(F_ov1* == real function(real)));
+    static assert(is(F_ov2* == int function(int)));
+    static assert(is(F_ov3* == int function() @property));
+
+    alias F_dglit = FunctionTypeOf!((int a){ return a; });
+    static assert(is(F_dglit* : int function(int)));
+}
+
+// std.traits.ReturnType
+/*
+Get the type of the return value from a function,
+a pointer to function, a delegate, a struct
+with an opCall, a pointer to a struct with an opCall,
+or a class with an `opCall`. Please note that $(D_KEYWORD ref)
+is not part of a type, but the attribute of the function
+(see template $(LREF functionAttributes)).
+*/
+template ReturnType(func...)
+if (func.length == 1 /*&& isCallable!func*/)
+{
+    static if (is(FunctionTypeOf!func R == return))
+        alias ReturnType = R;
+    else
+        static assert(0, "argument has no return type");
+}
+
+//
+@safe unittest
+{
+    int foo();
+    ReturnType!foo x;   // x is declared as int
+}
+
+@safe unittest
+{
+    struct G
+    {
+        int opCall (int i) { return 1;}
+    }
+
+    alias ShouldBeInt = ReturnType!G;
+    static assert(is(ShouldBeInt == int));
+
+    G g;
+    static assert(is(ReturnType!g == int));
+
+    G* p;
+    alias pg = ReturnType!p;
+    static assert(is(pg == int));
+
+    class C
+    {
+        int opCall (int i) { return 1;}
+    }
+
+    static assert(is(ReturnType!C == int));
+
+    C c;
+    static assert(is(ReturnType!c == int));
+
+    class Test
+    {
+        int prop() @property { return 0; }
+    }
+    alias R_Test_prop = ReturnType!(Test.prop);
+    static assert(is(R_Test_prop == int));
+
+    alias R_dglit = ReturnType!((int a) { return a; });
+    static assert(is(R_dglit == int));
+}
+
+// std.traits.Parameters
+/*
+Get, as a tuple, the types of the parameters to a function, a pointer
+to function, a delegate, a struct with an `opCall`, a pointer to a
+struct with an `opCall`, or a class with an `opCall`.
+*/
+template Parameters(func...)
+if (func.length == 1 /*&& isCallable!func*/)
+{
+    static if (is(FunctionTypeOf!func P == function))
+        alias Parameters = P;
+    else
+        static assert(0, "argument has no parameters");
+}
+
+//
+@safe unittest
+{
+    int foo(int, long);
+    void bar(Parameters!foo);      // declares void bar(int, long);
+    void abc(Parameters!foo[1]);   // declares void abc(long);
+}
+
+@safe unittest
+{
+    int foo(int i, bool b) { return 0; }
+    static assert(is(Parameters!foo == AliasSeq!(int, bool)));
+    static assert(is(Parameters!(typeof(&foo)) == AliasSeq!(int, bool)));
+
+    struct S { real opCall(real r, int i) { return 0.0; } }
+    S s;
+    static assert(is(Parameters!S == AliasSeq!(real, int)));
+    static assert(is(Parameters!(S*) == AliasSeq!(real, int)));
+    static assert(is(Parameters!s == AliasSeq!(real, int)));
+
+    class Test
+    {
+        int prop() @property { return 0; }
+    }
+    alias P_Test_prop = Parameters!(Test.prop);
+    static assert(P_Test_prop.length == 0);
+
+    alias P_dglit = Parameters!((int a){});
+    static assert(P_dglit.length == 1);
+    static assert(is(P_dglit[0] == int));
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/druntime-2.085.0/src/gc/impl/conservative/gc.d 
new/druntime-2.085.1/src/gc/impl/conservative/gc.d
--- old/druntime-2.085.0/src/gc/impl/conservative/gc.d  2019-02-15 
20:09:43.000000000 +0100
+++ new/druntime-2.085.1/src/gc/impl/conservative/gc.d  2019-03-28 
04:39:36.000000000 +0100
@@ -89,8 +89,8 @@
 
         // Declared as an extern instead of importing core.exception
         // to avoid inlining - see issue 13725.
-        void onInvalidMemoryOperationError() @nogc nothrow;
-        void onOutOfMemoryErrorNoGC() @nogc nothrow;
+        void onInvalidMemoryOperationError(void* pretend_sideffect = null) 
@trusted pure nothrow @nogc;
+        void onOutOfMemoryErrorNoGC() @trusted nothrow @nogc;
     }
 
     enum
@@ -2386,11 +2386,7 @@
             return 0;
 
         MonoTime start, stop, begin;
-
-        if (config.profile)
-        {
-            begin = start = currTime;
-        }
+        begin = start = currTime;
 
         debug(COLLECT_PRINTF) printf("Gcx.fullcollect()\n");
         //printf("\tpool address range = %p .. %p\n", minAddr, maxAddr);
@@ -3946,3 +3942,20 @@
     void* small = GC.malloc(100, BlkAttr.NO_SCAN);
     test(small);
 }
+
+unittest
+{
+    import core.memory;
+
+    auto now = currTime;
+    GC.ProfileStats stats1 = GC.profileStats();
+    GC.collect();
+    GC.ProfileStats stats2 = GC.profileStats();
+    auto diff = currTime - now;
+
+    assert(stats2.totalCollectionTime - stats1.totalCollectionTime <= diff);
+    assert(stats2.totalPauseTime - stats1.totalPauseTime <= 
stats2.totalCollectionTime - stats1.totalCollectionTime);
+
+    assert(stats2.maxPauseTime >= stats1.maxPauseTime);
+    assert(stats2.maxCollectionTime >= stats1.maxCollectionTime);
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/druntime-2.085.0/src/object.d 
new/druntime-2.085.1/src/object.d
--- old/druntime-2.085.0/src/object.d   2019-02-15 20:09:43.000000000 +0100
+++ new/druntime-2.085.1/src/object.d   2019-03-28 04:39:36.000000000 +0100
@@ -4158,13 +4158,12 @@
 
 template RTInfoImpl(size_t[] pointers)
 {
-    immutable size_t[pointers.length] data = pointers[];
-    immutable RTInfoImpl = data.ptr;
+    immutable size_t[pointers.length] RTInfoImpl = pointers[];
 }
 
 template RTInfo(T)
 {
-    enum RTInfo = RTInfoImpl!(__traits(getPointerBitmap, T));
+    enum RTInfo = RTInfoImpl!(__traits(getPointerBitmap, T)).ptr;
 }
 
 /**
@@ -4819,11 +4818,29 @@
 }
 
 // Allows customized assert error messages
-string _d_assert_fail(string comp, A, B)(A a, B b)
+string _d_assert_fail(string comp, A, B)(A a, B b) @nogc @safe nothrow pure
 {
-    import core.internal.dassert : invertCompToken, miniFormat;
-    auto valA = miniFormat(a);
-    auto valB = miniFormat(b);
+    import core.internal.dassert : invertCompToken, miniFormatFakeAttributes, 
pureAlloc;
+    /*
+    The program will be terminated after the assertion error message has
+    been printed and its not considered part of the "main" program.
+    Also, catching an AssertError is Undefined Behavior
+    Hence, we can fake purity and @nogc-ness here.
+    */
+
+    auto valA = miniFormatFakeAttributes(a);
+    auto valB = miniFormatFakeAttributes(b);
     enum token = invertCompToken(comp);
-    return valA ~ " " ~ token ~ " " ~ valB;
+
+    const totalLen = valA.length + token.length + valB.length + 2;
+    char[] buffer = cast(char[]) pureAlloc(totalLen)[0 .. totalLen];
+    // @nogc-concat of "<valA> <comp> <valB>"
+    auto n = valA.length;
+    buffer[0 .. n] = valA;
+    buffer[n++] = ' ';
+    buffer[n .. n + token.length] = token;
+    n += token.length;
+    buffer[n++] = ' ';
+    buffer[n .. n + valB.length] = valB;
+    return (() @trusted => cast(string) buffer)();
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/druntime-2.085.0/src/rt/lifetime.d 
new/druntime-2.085.1/src/rt/lifetime.d
--- old/druntime-2.085.0/src/rt/lifetime.d      2019-02-15 20:09:43.000000000 
+0100
+++ new/druntime-2.085.1/src/rt/lifetime.d      2019-03-28 04:39:36.000000000 
+0100
@@ -1420,12 +1420,12 @@
     }
 }
 
-extern (C) void rt_finalize(void* p, bool det = true)
+extern (C) void rt_finalize(void* p, bool det = true) nothrow
 {
     rt_finalize2(p, det, true);
 }
 
-extern (C) void rt_finalizeFromGC(void* p, size_t size, uint attr)
+extern (C) void rt_finalizeFromGC(void* p, size_t size, uint attr) nothrow
 {
     // to verify: reset memory necessary?
     if (!(attr & BlkAttr.STRUCTFINAL))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/druntime-2.085.0/test/exceptions/src/assert_fail.d 
new/druntime-2.085.1/test/exceptions/src/assert_fail.d
--- old/druntime-2.085.0/test/exceptions/src/assert_fail.d      2019-02-15 
20:09:43.000000000 +0100
+++ new/druntime-2.085.1/test/exceptions/src/assert_fail.d      2019-03-28 
04:39:36.000000000 +0100
@@ -110,6 +110,13 @@
     test([1:"one"], [2: "two"], `[1: "one"] != [2: "two"]`);
 }
 
+
+void testAttributes() @safe pure @nogc nothrow
+{
+    int a;
+    assert(a == 0);
+}
+
 void main()
 {
     testIntegers();
@@ -120,5 +127,6 @@
     testArray();
     testStruct();
     testAA();
+    testAttributes();
     fprintf(stderr, "success.\n");
 }

++++++ phobos-2.085.0.tar.gz -> phobos-2.085.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/phobos-2.085.0/std/algorithm/iteration.d 
new/phobos-2.085.1/std/algorithm/iteration.d
--- old/phobos-2.085.0/std/algorithm/iteration.d        2019-02-15 
20:09:48.000000000 +0100
+++ new/phobos-2.085.1/std/algorithm/iteration.d        2019-04-01 
03:32:18.000000000 +0200
@@ -1641,6 +1641,12 @@
         if (!_input.empty) popFront();
     }
 
+    private this(R input, Tuple!(MutableE, uint) current)
+    {
+        _input = input;
+        _current = current;
+    }
+
     ///
     void popFront()
     {
@@ -1684,11 +1690,9 @@
     static if (isForwardRange!R)
     {
         ///
-        @property typeof(this) save() {
-            typeof(this) ret = this;
-            ret._input = this._input.save;
-            ret._current = this._current;
-            return ret;
+        @property typeof(this) save()
+        {
+            return Group(_input.save, _current);
         }
     }
 }
@@ -1807,6 +1811,15 @@
     assert(t.equal([ tuple(3, 1u), tuple(4, 3u), tuple(5, 1u) ]));
 }
 
+pure @safe unittest // issue 18657
+{
+    import std.algorithm.comparison : equal;
+    import std.range : refRange;
+    auto r = refRange(&["foo"][0]).group;
+    assert(equal(r.save, "foo".group));
+    assert(equal(r, "foo".group));
+}
+
 // Used by implementation of chunkBy for non-forward input ranges.
 private struct ChunkByChunkImpl(alias pred, Range)
 if (isInputRange!Range && !isForwardRange!Range)
@@ -5149,6 +5162,24 @@
             _end = size_t.max;
     }
 
+    static if (fullSlicing)
+    {
+        private this(Range input, size_t end)
+        {
+            _input = input;
+            _end = end;
+        }
+    }
+    else
+    {
+        private this(Range input, size_t end, Range next)
+        {
+            _input = input;
+            _end = end;
+            _next = next;
+        }
+    }
+
     static if (isInfinite!Range)
     {
         enum bool empty = false;  // Propagate infiniteness.
@@ -5213,11 +5244,10 @@
 
     @property typeof(this) save()
     {
-        auto ret = this;
-        ret._input = _input.save;
-        static if (!fullSlicing)
-            ret._next = _next.save;
-        return ret;
+        static if (fullSlicing)
+            return SplitterResult(_input.save, _end);
+        else
+            return SplitterResult(_input.save, _end, _next.save);
     }
 }
 
@@ -5314,6 +5344,15 @@
     assert(equal(splitter!"a=='本'"("日本語"), ["日", "語"]));
 }
 
+pure @safe unittest // issue 18657
+{
+    import std.algorithm.comparison : equal;
+    import std.range : refRange;
+    auto r = refRange(&["foobar"][0]).splitter!(c => c == 'b');
+    assert(equal!equal(r.save, ["foo", "ar"]));
+    assert(equal!equal(r.save, ["foo", "ar"]));
+}
+
 /++
 Lazily splits the character-based range `s` into words, using whitespace as the
 delimiter.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/phobos-2.085.0/std/algorithm/searching.d 
new/phobos-2.085.1/std/algorithm/searching.d
--- old/phobos-2.085.0/std/algorithm/searching.d        2019-02-15 
20:09:48.000000000 +0100
+++ new/phobos-2.085.1/std/algorithm/searching.d        2019-04-01 
03:32:18.000000000 +0200
@@ -2684,7 +2684,7 @@
     InputRange seq, ForwardRange choices)
 if (isInputRange!InputRange && isForwardRange!ForwardRange)
 {
-    for (; !seq.empty && find!pred(choices, seq.front).empty; seq.popFront())
+    for (; !seq.empty && find!pred(choices.save, seq.front).empty; 
seq.popFront())
     {
     }
     return seq;
@@ -2708,6 +2708,14 @@
     assert(findAmong!("a == b")(b, [ 4, 6, 7 ][]).empty);
 }
 
+@system unittest // issue 19765
+{
+    import std.range.interfaces : inputRangeObject;
+    auto choices = inputRangeObject("b");
+    auto f = "foobar".findAmong(choices);
+    assert(f == "bar");
+}
+
 // findSkip
 /**
  * Finds `needle` in `haystack` and positions `haystack`
@@ -4913,6 +4921,7 @@
     private bool _done;
 
     static if (!is(Sentinel == void))
+    {
         ///
         this(Range input, Sentinel sentinel,
                 OpenRight openRight = Yes.openRight)
@@ -4922,7 +4931,17 @@
             _openRight = openRight;
             _done = _input.empty || openRight && predSatisfied();
         }
+        private this(Range input, Sentinel sentinel, OpenRight openRight,
+            bool done)
+        {
+            _input = input;
+            _sentinel = sentinel;
+            _openRight = openRight;
+            _done = done;
+        }
+    }
     else
+    {
         ///
         this(Range input, OpenRight openRight = Yes.openRight)
         {
@@ -4930,6 +4949,13 @@
             _openRight = openRight;
             _done = _input.empty || openRight && predSatisfied();
         }
+        private this(Range input, OpenRight openRight, bool done)
+        {
+            _input = input;
+            _openRight = openRight;
+            _done = done;
+        }
+    }
 
     ///
     @property bool empty()
@@ -4971,27 +4997,14 @@
 
     static if (isForwardRange!Range)
     {
-        static if (!is(Sentinel == void))
-            ///
-            @property Until save()
-            {
-                Until result = this;
-                result._input     = _input.save;
-                result._sentinel  = _sentinel;
-                result._openRight = _openRight;
-                result._done      = _done;
-                return result;
-            }
-        else
-            ///
-            @property Until save()
-            {
-                Until result = this;
-                result._input     = _input.save;
-                result._openRight = _openRight;
-                result._done      = _done;
-                return result;
-            }
+        ///
+        @property Until save()
+        {
+            static if (is(Sentinel == void))
+                return Until(_input.save, _openRight, _done);
+            else
+                return Until(_input.save, _sentinel, _openRight, _done);
+        }
     }
 }
 
@@ -5043,3 +5056,19 @@
     auto s = "hello how\nare you";
     assert(equal(s.until!(c => c.among!('\n', '\r')), "hello how"));
 }
+
+pure @safe unittest // issue 18657
+{
+    import std.algorithm.comparison : equal;
+    import std.range : refRange;
+    {
+        auto r = refRange(&["foobar"][0]).until("bar");
+        assert(equal(r.save, "foo"));
+        assert(equal(r.save, "foo"));
+    }
+    {
+        auto r = refRange(&["foobar"][0]).until!(e => e == 'b');
+        assert(equal(r.save, "foo"));
+        assert(equal(r.save, "foo"));
+    }
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/phobos-2.085.0/std/range/package.d 
new/phobos-2.085.1/std/range/package.d
--- old/phobos-2.085.0/std/range/package.d      2019-02-15 20:09:48.000000000 
+0100
+++ new/phobos-2.085.1/std/range/package.d      2019-04-01 03:32:18.000000000 
+0200
@@ -972,12 +972,20 @@
             static if (allSatisfy!(isForwardRange, R))
                 @property auto save()
                 {
-                    typeof(this) result = this;
-                    foreach (i, Unused; R)
+                    auto saveSource(size_t len)()
                     {
-                        result.source[i] = result.source[i].save;
+                        import std.typecons : tuple;
+                        static if (len == 0)
+                        {
+                            return tuple();
+                        }
+                        else
+                        {
+                            return saveSource!(len - 1)() ~
+                                tuple(source[len - 1].save);
+                        }
                     }
-                    return result;
+                    return Result(saveSource!(R.length).expand);
                 }
 
             void popFront()
@@ -1380,6 +1388,14 @@
     assert(chain(a, b).empty);
 }
 
+pure @safe unittest // issue 18657
+{
+    import std.algorithm.comparison : equal;
+    auto r = refRange(&["foo"][0]).chain("bar");
+    assert(equal(r.save, "foobar"));
+    assert(equal(r, "foobar"));
+}
+
 /**
 Choose one of two ranges at runtime depending on a Boolean condition.
 
@@ -1513,9 +1529,9 @@
     static if (isForwardRange!R1 && isForwardRange!R2)
         @property auto save()
         {
-            auto result = this;
-            actOnChosen!((ref r) { r = r.save; })(result);
-            return result;
+            return r1Chosen
+                ? ChooseResult(r1Chosen, r1.save, r2)
+                : ChooseResult(r1Chosen, r1, r2.save);
         }
 
     @property void front(T)(T v)
@@ -1602,6 +1618,14 @@
         }
 }
 
+pure @safe unittest // issue 18657
+{
+    import std.algorithm.comparison : equal;
+    auto r = choose(true, refRange(&["foo"][0]), "bar");
+    assert(equal(r.save, "foo"));
+    assert(equal(r, "foo"));
+}
+
 /**
 Choose one of multiple ranges at runtime.
 
@@ -1822,12 +1846,20 @@
         static if (allSatisfy!(isForwardRange, staticMap!(Unqual, Rs)))
             @property auto save()
             {
-                Result result = this;
-                foreach (i, Unused; Rs)
+                auto saveSource(size_t len)()
                 {
-                    result.source[i] = result.source[i].save;
+                    import std.typecons : tuple;
+                    static if (len == 0)
+                    {
+                        return tuple();
+                    }
+                    else
+                    {
+                        return saveSource!(len - 1)() ~
+                            tuple(source[len - 1].save);
+                    }
                 }
-                return result;
+                return Result(saveSource!(Rs.length).expand, _current);
             }
 
         static if (allSatisfy!(hasLength, Rs))
@@ -1885,6 +1917,14 @@
     assert(interleave([1, 2, 3], 0).equal([1, 0, 2, 0, 3]));
 }
 
+pure @safe unittest
+{
+    import std.algorithm.comparison : equal;
+    auto r = roundRobin(refRange(&["foo"][0]), refRange(&["bar"][0]));
+    assert(equal(r.save, "fboaor"));
+    assert(equal(r.save, "fboaor"));
+}
+
 /**
 Iterates a random-access range starting from a given point and
 progressively extending left and right from that point. If no initial
@@ -3750,6 +3790,12 @@
             _current = input.save;
         }
 
+        private this(R original, R current)
+        {
+            _original = original;
+            _current = current;
+        }
+
         /// ditto
         @property auto ref front()
         {
@@ -3789,10 +3835,7 @@
         @property Cycle save()
         {
             //No need to call _original.save, because Cycle never actually 
modifies _original
-            Cycle ret = this;
-            ret._original = _original;
-            ret._current =  _current.save;
-            return ret;
+            return Cycle(_original, _current.save);
         }
     }
 }
@@ -4104,6 +4147,14 @@
     assertThrown!AssertError(cycle([0, 1, 2][0 .. 0]));
 }
 
+pure @safe unittest // issue 18657
+{
+    import std.algorithm.comparison : equal;
+    auto r = refRange(&["foo"][0]).cycle.take(4);
+    assert(equal(r.save, "foof"));
+    assert(equal(r.save, "foof"));
+}
+
 private alias lengthType(R) = typeof(R.init.length.init);
 
 /**
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/phobos-2.085.0/std/variant.d 
new/phobos-2.085.1/std/variant.d
--- old/phobos-2.085.0/std/variant.d    2019-02-15 20:09:48.000000000 +0100
+++ new/phobos-2.085.1/std/variant.d    2019-04-01 03:32:18.000000000 +0200
@@ -726,7 +726,7 @@
     }
 
     ///
-    version (unittest)
+    version (StdDdoc)
     @system unittest
     {
         Variant a;
@@ -759,7 +759,7 @@
     }
 
     ///
-    version (unittest)
+    version (StdDdoc)
     @system unittest
     {
         Variant a = 5;
@@ -1097,7 +1097,7 @@
     }
 
     ///
-    version (unittest)
+    version (StdDdoc)
     @system unittest
     {
         Variant a = new int[10];


Reply via email to