Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Issue 21183 - schwartzSort does not strip const #7602

Merged
merged 1 commit into from
Aug 21, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 38 additions & 2 deletions std/algorithm/sorting.d
Original file line number Diff line number Diff line change
Expand Up @@ -2981,18 +2981,25 @@ if (isRandomAccessRange!R && hasLength!R && hasSwappableElements!R &&
static if (is(typeof(unaryFun!transform(r.front))))
{
alias transformFun = unaryFun!transform;
alias T = typeof(transformFun(r.front));
alias TB = typeof(transformFun(r.front));
enum isBinary = false;
}
else static if (is(typeof(binaryFun!transform(r.front, 0))))
{
alias transformFun = binaryFun!transform;
alias T = typeof(transformFun(r.front, 0));
alias TB = typeof(transformFun(r.front, 0));
enum isBinary = true;
}
else
static assert(false, "unsupported `transform` alias");

// The `transform` function might return a qualified type, e.g. const(int).
// Strip qualifiers if possible s.t. the temporary array is sortable.
static if (is(TB : Unqual!TB))
alias T = Unqual!TB;
else
static assert(false, "`transform` returns an unsortable qualified type: " ~ TB.stringof);

static trustedMalloc(size_t len) @trusted
{
import core.checkedint : mulu;
Expand Down Expand Up @@ -3168,6 +3175,35 @@ if (isRandomAccessRange!R && hasLength!R && hasSwappableElements!R)
assert(arr.isSorted());
}

// https://issues.dlang.org/show_bug.cgi?id=21183
@safe unittest
{
static T get(T)(int) { return T.init; }

// There's no need to actually sort, just checking type interference
if (false)
{
int[] arr;

// Fine because there are no indirections
arr.schwartzSort!(get!(const int));

// Fine because it decays to immutable(int)*
arr.schwartzSort!(get!(immutable int*));

// Disallowed because it would require a non-const reference
static assert(!__traits(compiles, arr.schwartzSort!(get!(const Object))));

static struct Wrapper
{
int* ptr;
}

// Disallowed because Wrapper.ptr would become mutable
static assert(!__traits(compiles, arr.schwartzSort!(get!(const Wrapper))));
}
}

// partialSort
/**
Reorders the random-access range `r` such that the range `r[0 .. mid]`
Expand Down