Skip to content

Commit 34ff27e

Browse files
jmdavisdlang-bot
authored andcommitted
Work around bugzilla issue 24415 - only doesn't work with elements with a copy constructor.
Since the compiler is treating the auto-generated copy-constructor for OnlyResult as private (thus rendering it useless outside of std.range.package), this commit adds an explicit one and makes it public. Once the dmd bug has been fixed, the explicit copy constructor should be removed.
1 parent fc7273b commit 34ff27e

File tree

2 files changed

+99
-0
lines changed

2 files changed

+99
-0
lines changed

std/internal/test/range.d

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,94 @@ module std.internal.test.range;
2323
auto r = R().chunks(3);
2424
assert(r.equal!equal([[ 0, 1, 2 ], [ 3, 4 ]]));
2525
}
26+
27+
// https://issues.dlang.org/show_bug.cgi?id=24415
28+
@safe unittest
29+
{
30+
import std.range : only;
31+
32+
static struct S(T)
33+
{
34+
T i;
35+
36+
this(ref return scope inout(S) rhs) scope @safe inout pure nothrow
37+
{
38+
i = rhs.i;
39+
}
40+
}
41+
{
42+
auto a = only(S!int(42));
43+
auto b = a;
44+
assert(!b.empty);
45+
assert(b.front == S!int(42));
46+
47+
a.popFront();
48+
auto c = a;
49+
assert(c.empty);
50+
}
51+
{
52+
auto a = only(S!(const int)(42));
53+
auto b = a;
54+
assert(!b.empty);
55+
assert(b.front == S!(const int)(42));
56+
57+
a.popFront();
58+
auto c = a;
59+
assert(c.empty);
60+
}
61+
{
62+
auto a = only(S!(immutable int)(42));
63+
auto b = a;
64+
assert(!b.empty);
65+
assert(b.front == S!(immutable int)(42));
66+
67+
a.popFront();
68+
auto c = a;
69+
assert(c.empty);
70+
}
71+
{
72+
auto a = only(S!int(42), S!int(192));
73+
auto b = a;
74+
assert(!b.empty);
75+
assert(b.front == S!int(42));
76+
77+
a.popFront();
78+
auto c = a;
79+
assert(!c.empty);
80+
assert(c.front == S!int(192));
81+
82+
a.popFront();
83+
auto d = a;
84+
assert(d.empty);
85+
}
86+
{
87+
auto a = only(S!(const int)(42), S!(const int)(192));
88+
auto b = a;
89+
assert(!b.empty);
90+
assert(b.front == S!(const int)(42));
91+
92+
a.popFront();
93+
auto c = a;
94+
assert(!c.empty);
95+
assert(c.front == S!(const int)(192));
96+
97+
a.popFront();
98+
auto d = a;
99+
assert(d.empty);
100+
}
101+
{
102+
auto a = only(S!(immutable int)(42), S!(immutable int)(192));
103+
auto b = a;
104+
assert(!b.empty);
105+
assert(b.front == S!(immutable int)(42));
106+
107+
a.popFront();
108+
auto c = a;
109+
assert(!c.empty);
110+
assert(c.front == S!(immutable int)(192));
111+
112+
a.popFront();
113+
auto d = a;
114+
assert(d.empty);
115+
}
116+
}

std/range/package.d

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10375,6 +10375,14 @@ private struct OnlyResult(T)
1037510375
}
1037610376
alias opDollar = length;
1037710377

10378+
// FIXME Workaround for https://issues.dlang.org/show_bug.cgi?id=24415
10379+
import std.traits : hasElaborateCopyConstructor;
10380+
static if (hasElaborateCopyConstructor!T)
10381+
{
10382+
private static struct WorkaroundBugzilla24415 {}
10383+
public this()(WorkaroundBugzilla24415) {}
10384+
}
10385+
1037810386
private this()(return scope auto ref T value)
1037910387
{
1038010388
ref @trusted unqual(ref T x){return cast() x;}

0 commit comments

Comments
 (0)