From f61c94ab1fb955cd0f288bd1ee0ea577a5ba7736 Mon Sep 17 00:00:00 2001 From: Vladimir Panteleev Date: Tue, 6 Jul 2021 15:17:52 +0000 Subject: [PATCH] Fix Issue 22107 - [scope][dip1000] Can't .dup an array of structs with impure copy constructor --- src/object.d | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/object.d b/src/object.d index fcf1b01e48..6acc09677e 100644 --- a/src/object.d +++ b/src/object.d @@ -3491,7 +3491,7 @@ private U[] _dup(T, U)(scope T[] a) pure nothrow @trusted if (__traits(isPOD, T) return *cast(U[]*) &arr; } -private U[] _dupCtfe(T, U)(T[] a) +private U[] _dupCtfe(T, U)(scope T[] a) { static if (is(T : void)) assert(0, "Cannot dup a void[] array at compile time."); @@ -3524,6 +3524,21 @@ private U[] _dup(T, U)(T[] a) if (!__traits(isPOD, T)) return res; } +// https://issues.dlang.org/show_bug.cgi?id=22107 +@safe unittest +{ + static int i; + @safe struct S + { + this(this) { i++; } + } + + void fun(scope S[] values...) @safe + { + values.dup; + } +} + // HACK: This is a lie. `_d_arraysetcapacity` is neither `nothrow` nor `pure`, but this lie is // necessary for now to prevent breaking code. private extern (C) size_t _d_arraysetcapacity(const TypeInfo ti, size_t newcapacity, void[]* arrptr) pure nothrow;