Fix Issue 21183 - schwartzSort does not strip const

Fixed by using the unqualified type if possible
This commit is contained in:
MoonlightSentinel 2020-08-21 13:07:57 +02:00
parent 1f1a80d0a0
commit 255f9496d1
No known key found for this signature in database
GPG key ID: 1A1A60AECDC956AB

View file

@ -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;
@ -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]`