Skip to content

Commit

Permalink
Work around bugzilla issue 24415 - only doesn't work with elements wi…
Browse files Browse the repository at this point in the history
…th 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.
  • Loading branch information
jmdavis authored and dlang-bot committed Apr 9, 2024
1 parent fc7273b commit 34ff27e
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 0 deletions.
91 changes: 91 additions & 0 deletions std/internal/test/range.d
Expand Up @@ -23,3 +23,94 @@ module std.internal.test.range;
auto r = R().chunks(3);
assert(r.equal!equal([[ 0, 1, 2 ], [ 3, 4 ]]));
}

// https://issues.dlang.org/show_bug.cgi?id=24415
@safe unittest
{
import std.range : only;

static struct S(T)
{
T i;

this(ref return scope inout(S) rhs) scope @safe inout pure nothrow
{
i = rhs.i;
}
}
{
auto a = only(S!int(42));
auto b = a;
assert(!b.empty);
assert(b.front == S!int(42));

a.popFront();
auto c = a;
assert(c.empty);
}
{
auto a = only(S!(const int)(42));
auto b = a;
assert(!b.empty);
assert(b.front == S!(const int)(42));

a.popFront();
auto c = a;
assert(c.empty);
}
{
auto a = only(S!(immutable int)(42));
auto b = a;
assert(!b.empty);
assert(b.front == S!(immutable int)(42));

a.popFront();
auto c = a;
assert(c.empty);
}
{
auto a = only(S!int(42), S!int(192));
auto b = a;
assert(!b.empty);
assert(b.front == S!int(42));

a.popFront();
auto c = a;
assert(!c.empty);
assert(c.front == S!int(192));

a.popFront();
auto d = a;
assert(d.empty);
}
{
auto a = only(S!(const int)(42), S!(const int)(192));
auto b = a;
assert(!b.empty);
assert(b.front == S!(const int)(42));

a.popFront();
auto c = a;
assert(!c.empty);
assert(c.front == S!(const int)(192));

a.popFront();
auto d = a;
assert(d.empty);
}
{
auto a = only(S!(immutable int)(42), S!(immutable int)(192));
auto b = a;
assert(!b.empty);
assert(b.front == S!(immutable int)(42));

a.popFront();
auto c = a;
assert(!c.empty);
assert(c.front == S!(immutable int)(192));

a.popFront();
auto d = a;
assert(d.empty);
}
}
8 changes: 8 additions & 0 deletions std/range/package.d
Expand Up @@ -10375,6 +10375,14 @@ private struct OnlyResult(T)
}
alias opDollar = length;

// FIXME Workaround for https://issues.dlang.org/show_bug.cgi?id=24415
import std.traits : hasElaborateCopyConstructor;
static if (hasElaborateCopyConstructor!T)
{
private static struct WorkaroundBugzilla24415 {}
public this()(WorkaroundBugzilla24415) {}
}

private this()(return scope auto ref T value)
{
ref @trusted unqual(ref T x){return cast() x;}
Expand Down

0 comments on commit 34ff27e

Please sign in to comment.