aboutsummaryrefslogtreecommitdiff
path: root/libphobos/src
diff options
context:
space:
mode:
Diffstat (limited to 'libphobos/src')
-rw-r--r--libphobos/src/MERGE2
-rw-r--r--libphobos/src/std/algorithm/internal.d2
-rw-r--r--libphobos/src/std/bigint.d16
-rw-r--r--libphobos/src/std/container/rbtree.d16
-rw-r--r--libphobos/src/std/conv.d2
-rw-r--r--libphobos/src/std/file.d27
-rw-r--r--libphobos/src/std/functional.d9
-rw-r--r--libphobos/src/std/internal/math/biguintcore.d6
-rw-r--r--libphobos/src/std/socket.d17
-rw-r--r--libphobos/src/std/sumtype.d20
-rw-r--r--libphobos/src/std/typecons.d42
-rw-r--r--libphobos/src/std/uni/package.d2
-rw-r--r--libphobos/src/std/zip.d35
13 files changed, 119 insertions, 77 deletions
diff --git a/libphobos/src/MERGE b/libphobos/src/MERGE
index 2babfbe..b5b939f 100644
--- a/libphobos/src/MERGE
+++ b/libphobos/src/MERGE
@@ -1,4 +1,4 @@
-896b1d0e1e8b69bccac0e180ecd1b42a70f95d5b
+1a3e80ec25afab6123cdcfe20186f36f006b68bb
The first line of this file holds the git revision number of the last
merge done from the dlang/phobos repository.
diff --git a/libphobos/src/std/algorithm/internal.d b/libphobos/src/std/algorithm/internal.d
index 3caeefeb..6b45599 100644
--- a/libphobos/src/std/algorithm/internal.d
+++ b/libphobos/src/std/algorithm/internal.d
@@ -62,4 +62,6 @@ version (StdUnittest)
}
}
+// Used instead of `&object.member` when `member` may be
+// either a field or a @property function.
package(std) T* addressOf(T)(ref T val) { return &val; }
diff --git a/libphobos/src/std/bigint.d b/libphobos/src/std/bigint.d
index bbb55c2..b2fcc071 100644
--- a/libphobos/src/std/bigint.d
+++ b/libphobos/src/std/bigint.d
@@ -414,17 +414,17 @@ public:
/**
* Implements assignment operators of the form `BigInt op= BigInt`.
*/
- BigInt opOpAssign(string op, T)(T y) pure nothrow @safe scope return
+ BigInt opOpAssign(string op, T)(T y) pure nothrow @safe return scope
if ((op=="+" || op== "-" || op=="*" || op=="|" || op=="&" || op=="^" || op=="/" || op=="%")
&& is (T: BigInt))
{
static if (op == "+")
{
- data = BigUint.addOrSub(data, y.data, sign != y.sign, &sign);
+ data = BigUint.addOrSub(data, y.data, sign != y.sign, sign);
}
else static if (op == "-")
{
- data = BigUint.addOrSub(data, y.data, sign == y.sign, &sign);
+ data = BigUint.addOrSub(data, y.data, sign == y.sign, sign);
}
else static if (op == "*")
{
@@ -2244,7 +2244,7 @@ void divMod(const BigInt dividend, const BigInt divisor, out BigInt quotient, ou
BigUint.divMod(dividend.data, divisor.data, q, r);
quotient.sign = dividend.sign != divisor.sign;
quotient.data = q;
- remainder.sign = dividend.sign;
+ remainder.sign = r.isZero() ? false : dividend.sign;
remainder.data = r;
}
@@ -2291,6 +2291,14 @@ void divMod(const BigInt dividend, const BigInt divisor, out BigInt quotient, ou
assert(q * d + r == -c);
}
+// https://issues.dlang.org/show_bug.cgi?id=22771
+@safe pure nothrow unittest
+{
+ BigInt quotient, remainder;
+ divMod(BigInt(-50), BigInt(1), quotient, remainder);
+ assert(remainder == 0);
+}
+
// https://issues.dlang.org/show_bug.cgi?id=19740
@safe unittest
{
diff --git a/libphobos/src/std/container/rbtree.d b/libphobos/src/std/container/rbtree.d
index 0b0a0b2..622dee4 100644
--- a/libphobos/src/std/container/rbtree.d
+++ b/libphobos/src/std/container/rbtree.d
@@ -111,7 +111,7 @@ struct RBNode(V)
/**
* Get the left child
*/
- @property inout(RBNode)* left() inout
+ @property inout(RBNode)* left() inout return scope
{
return _left;
}
@@ -119,7 +119,7 @@ struct RBNode(V)
/**
* Get the right child
*/
- @property inout(RBNode)* right() inout
+ @property inout(RBNode)* right() inout return scope
{
return _right;
}
@@ -127,7 +127,7 @@ struct RBNode(V)
/**
* Get the parent
*/
- @property inout(RBNode)* parent() inout
+ @property inout(RBNode)* parent() inout return scope
{
return _parent;
}
@@ -377,7 +377,7 @@ struct RBNode(V)
* Returns the next highest valued node in the tree after this one, or end
* if this was the highest-valued node.
*/
- Node remove(Node end)
+ Node remove(Node end) return
{
//
// remove this node from the tree, fixing the color if necessary.
@@ -558,7 +558,7 @@ struct RBNode(V)
/**
* Return the leftmost descendant of this node.
*/
- @property inout(RBNode)* leftmost() inout
+ @property inout(RBNode)* leftmost() inout return
{
inout(RBNode)* result = &this;
while (result._left !is null)
@@ -569,7 +569,7 @@ struct RBNode(V)
/**
* Return the rightmost descendant of this node
*/
- @property inout(RBNode)* rightmost() inout
+ @property inout(RBNode)* rightmost() inout return
{
inout(RBNode)* result = &this;
while (result._right !is null)
@@ -583,7 +583,7 @@ struct RBNode(V)
* You should never call this on the marker node, as it is assumed that
* there is a valid next node.
*/
- @property inout(RBNode)* next() inout
+ @property inout(RBNode)* next() inout return
{
inout(RBNode)* n = &this;
if (n.right is null)
@@ -602,7 +602,7 @@ struct RBNode(V)
* You should never call this on the leftmost node of the tree as it is
* assumed that there is a valid previous node.
*/
- @property inout(RBNode)* prev() inout
+ @property inout(RBNode)* prev() inout return
{
inout(RBNode)* n = &this;
if (n.left is null)
diff --git a/libphobos/src/std/conv.d b/libphobos/src/std/conv.d
index a10f4da..8512a44 100644
--- a/libphobos/src/std/conv.d
+++ b/libphobos/src/std/conv.d
@@ -1642,7 +1642,7 @@ if (!isImplicitlyConvertible!(S, T) &&
Array-to-array conversion (except when target is a string type)
converts each element in turn by using `to`.
*/
-private T toImpl(T, S)(S value)
+private T toImpl(T, S)(scope S value)
if (!isImplicitlyConvertible!(S, T) &&
!isSomeString!S && isDynamicArray!S &&
!isExactSomeString!T && isArray!T)
diff --git a/libphobos/src/std/file.d b/libphobos/src/std/file.d
index c974ada..a99c517 100644
--- a/libphobos/src/std/file.d
+++ b/libphobos/src/std/file.d
@@ -4635,7 +4635,7 @@ private struct DirIteratorImpl
import std.path : chainPath;
auto searchPattern = chainPath(directory, "*.*");
- static auto trustedFindFirstFileW(typeof(searchPattern) pattern, WIN32_FIND_DATAW* findinfo) @trusted
+ static auto trustedFindFirstFileW(typeof(searchPattern) pattern, scope WIN32_FIND_DATAW* findinfo) @trusted
{
return FindFirstFileW(pattern.tempCString!FSChar(), findinfo);
}
@@ -4653,7 +4653,7 @@ private struct DirIteratorImpl
return toNext(true, &_findinfo);
}
- bool toNext(bool fetch, WIN32_FIND_DATAW* findinfo) @trusted
+ bool toNext(bool fetch, scope WIN32_FIND_DATAW* findinfo) @trusted
{
import core.stdc.wchar_ : wcscmp;
@@ -5274,7 +5274,21 @@ Returns:
*/
string tempDir() @trusted
{
- import std.path : dirSeparator;
+ // We must check that the end of a path is not a separator, before adding another
+ // If we don't we end up with https://issues.dlang.org/show_bug.cgi?id=22738
+ static string addSeparator(string input)
+ {
+ import std.path : dirSeparator;
+ import std.algorithm.searching : endsWith;
+
+ // It is very rare a directory path will reach this point with a directory separator at the end
+ // However on OSX this can happen, so we must verify lest we break user code i.e. https://github.com/dlang/dub/pull/2208
+ if (!input.endsWith(dirSeparator))
+ return input ~ dirSeparator;
+ else
+ return input;
+ }
+
static string cache;
if (cache is null)
{
@@ -5294,7 +5308,7 @@ string tempDir() @trusted
static string findExistingDir(T...)(lazy T alternatives)
{
foreach (dir; alternatives)
- if (!dir.empty && exists(dir)) return dir ~ dirSeparator;
+ if (!dir.empty && exists(dir)) return addSeparator(dir);
return null;
}
@@ -5309,7 +5323,7 @@ string tempDir() @trusted
if (cache is null)
{
- cache = getcwd() ~ dirSeparator;
+ cache = addSeparator(getcwd());
}
}
return cache;
@@ -5338,6 +5352,9 @@ string tempDir() @trusted
import std.algorithm.searching : endsWith;
import std.path : dirSeparator;
assert(tempDir.endsWith(dirSeparator));
+
+ // https://issues.dlang.org/show_bug.cgi?id=22738
+ assert(!tempDir.endsWith(dirSeparator ~ dirSeparator));
}
/**
diff --git a/libphobos/src/std/functional.d b/libphobos/src/std/functional.d
index bc8d368..da698e0 100644
--- a/libphobos/src/std/functional.d
+++ b/libphobos/src/std/functional.d
@@ -68,6 +68,8 @@ import std.traits : isCallable, Parameters;
import std.internal.attributes : betterC;
+public import core.lifetime : forward;
+
private template needOpCallAlias(alias fun)
{
/* Determine whether or not unaryFun and binaryFun need to alias to fun or
@@ -1845,10 +1847,3 @@ if (isCallable!(F))
static assert(! is(typeof(dg_xtrnC) == typeof(dg_xtrnD)));
}
}
-
-// forward used to be here but was moved to druntime
-template forward(args...)
-{
- import core.lifetime : fun = forward;
- alias forward = fun!args;
-}
diff --git a/libphobos/src/std/internal/math/biguintcore.d b/libphobos/src/std/internal/math/biguintcore.d
index 6a93e0a..d5c4768 100644
--- a/libphobos/src/std/internal/math/biguintcore.d
+++ b/libphobos/src/std/internal/math/biguintcore.d
@@ -813,7 +813,7 @@ public:
// If wantSub is false, return x + y, leaving sign unchanged.
// If wantSub is true, return abs(x - y), negating sign if x<y
- static BigUint addOrSub(scope BigUint x, scope BigUint y, bool wantSub, bool *sign)
+ static BigUint addOrSub(scope BigUint x, scope BigUint y, bool wantSub, ref bool sign)
pure nothrow @safe
{
BigUint r;
@@ -822,10 +822,10 @@ public:
bool negative;
// sub returns GC allocated array, can be safely cast to immutable
r.data = (() @trusted => cast(immutable) sub(x.data, y.data, &negative))();
- *sign ^= negative;
+ sign ^= negative;
if (r.isZero())
{
- *sign = false;
+ sign = false;
}
}
else
diff --git a/libphobos/src/std/socket.d b/libphobos/src/std/socket.d
index f8908cf..cd23232 100644
--- a/libphobos/src/std/socket.d
+++ b/libphobos/src/std/socket.d
@@ -787,13 +787,20 @@ class InternetHost
assert(ih.name == "www.digitalmars.com" || ih.name == "digitalmars.com",
ih.name);
- assert(ih.getHostByAddr(ih.addrList[0]));
- string getHostNameFromInt = ih.name.dup;
+ /* The following assert randomly fails in the test suite.
+ * https://issues.dlang.org/show_bug.cgi?id=22791
+ * So just ignore it when it fails.
+ */
+ //assert(ih.getHostByAddr(ih.addrList[0]));
+ if (ih.getHostByAddr(ih.addrList[0]))
+ {
+ string getHostNameFromInt = ih.name.dup;
- assert(ih.getHostByAddr(ia.toAddrString()));
- string getHostNameFromStr = ih.name.dup;
+ assert(ih.getHostByAddr(ia.toAddrString()));
+ string getHostNameFromStr = ih.name.dup;
- assert(getHostNameFromInt == getHostNameFromStr);
+ assert(getHostNameFromInt == getHostNameFromStr);
+ }
}
diff --git a/libphobos/src/std/sumtype.d b/libphobos/src/std/sumtype.d
index 658fd38..5e35a6b 100644
--- a/libphobos/src/std/sumtype.d
+++ b/libphobos/src/std/sumtype.d
@@ -262,6 +262,8 @@ private enum isHashable(T) = __traits(compiles,
private enum hasPostblit(T) = __traits(hasPostblit, T);
+private enum isInout(T) = is(T == inout);
+
/**
* A [tagged union](https://en.wikipedia.org/wiki/Tagged_union) that can hold a
* single value from any of a specified set of types.
@@ -419,6 +421,7 @@ public:
(
allSatisfy!(isCopyable, Map!(InoutOf, Types))
&& !anySatisfy!(hasPostblit, Map!(InoutOf, Types))
+ && allSatisfy!(isInout, Map!(InoutOf, Types))
)
{
/// Constructs a `SumType` that's a copy of another `SumType`.
@@ -1492,6 +1495,23 @@ version (D_BetterC) {} else
immutable SumType!(int*) si = &ni;
}
+// Immutable member type with copy constructor
+// https://issues.dlang.org/show_bug.cgi?id=22572
+@safe unittest
+{
+ static struct CopyConstruct
+ {
+ this(ref inout CopyConstruct other) inout {}
+ }
+
+ static immutable struct Value
+ {
+ CopyConstruct c;
+ }
+
+ SumType!Value s;
+}
+
/// True if `T` is an instance of the `SumType` template, otherwise false.
private enum bool isSumTypeInstance(T) = is(T == SumType!Args, Args...);
diff --git a/libphobos/src/std/typecons.d b/libphobos/src/std/typecons.d
index 28edb9b..ea8f8bd 100644
--- a/libphobos/src/std/typecons.d
+++ b/libphobos/src/std/typecons.d
@@ -2798,13 +2798,24 @@ struct Nullable(T)
}
}
- this (ref return scope inout Nullable!T rhs) inout
+ static if (__traits(hasPostblit, T))
{
- _isNull = rhs._isNull;
- if (!_isNull)
- _value.payload = rhs._value.payload;
- else
- _value = DontCallDestructorT.init;
+ this(this)
+ {
+ if (!_isNull)
+ _value.payload.__xpostblit();
+ }
+ }
+ else static if (__traits(hasCopyConstructor, T))
+ {
+ this(ref return scope inout Nullable!T rhs) inout
+ {
+ _isNull = rhs._isNull;
+ if (!_isNull)
+ _value.payload = rhs._value.payload;
+ else
+ _value = DontCallDestructorT.init;
+ }
}
/**
@@ -9630,13 +9641,28 @@ unittest
{
int b;
@disable this(this);
- this (ref return scope inout S rhs) inout
+ this(ref return scope inout S rhs) inout
{
this.b = rhs.b + 1;
}
}
Nullable!S s1 = S(1);
+ assert(s1.get().b == 2);
+ Nullable!S s2 = s1;
+ assert(s2.get().b == 3);
+}
+
+@safe unittest
+{
+ static struct S
+ {
+ int b;
+ this(this) { ++b; }
+ }
+
+ Nullable!S s1 = S(1);
+ assert(s1.get().b == 2);
Nullable!S s2 = s1;
- assert(s2.get().b > s1.get().b);
+ assert(s2.get().b == 3);
}
diff --git a/libphobos/src/std/uni/package.d b/libphobos/src/std/uni/package.d
index 192b6fd..9780b1b 100644
--- a/libphobos/src/std/uni/package.d
+++ b/libphobos/src/std/uni/package.d
@@ -5363,7 +5363,7 @@ pure @safe unittest
pure @safe unittest
{
import std.range : stride;
- static bool testAll(Matcher, Range)(scope ref Matcher m, ref Range r)
+ static bool testAll(Matcher, Range)(ref Matcher m, ref Range r) @safe
{
bool t = m.test(r);
auto save = r.idx;
diff --git a/libphobos/src/std/zip.d b/libphobos/src/std/zip.d
index 4d7422b..72d1287 100644
--- a/libphobos/src/std/zip.d
+++ b/libphobos/src/std/zip.d
@@ -222,14 +222,6 @@ final class ArchiveMember
@property @safe pure nothrow @nogc uint expandedSize() const { return _expandedSize; }
/**
- * Should be 0.
- *
- * Returns: The number of the disk where this member can be found.
- */
- deprecated("Multidisk not supported; will be removed in 2.099.0")
- @property @safe pure nothrow @nogc ushort diskNumber() const { return 0; }
-
- /**
* Data of member in compressed form.
*
* Returns: The file data in compressed form.
@@ -452,13 +444,6 @@ public:
private bool _isZip64;
static const ushort zip64ExtractVersion = 45;
- deprecated("Use digitalSignatureLength instead; will be removed in 2.098.0")
- static const int digiSignLength = 6;
- deprecated("Use zip64EndOfCentralDirLocatorLength instead; will be removed in 2.098.0")
- static const int eocd64LocLength = 20;
- deprecated("Use zip64EndOfCentralDirLength instead; will be removed in 2.098.0")
- static const int eocd64Length = 56;
-
private Segment[] _segs;
/**
@@ -469,29 +454,11 @@ public:
@property @safe @nogc pure nothrow ubyte[] data() { return _data; }
/**
- * 0 since multi-disk zip archives are not supported.
- *
- * Returns: Number of this disk.
- */
- deprecated("Multidisk not supported; will be removed in 2.099.0")
- @property @safe @nogc pure nothrow uint diskNumber() const { return 0; }
-
- /**
- * 0 since multi-disk zip archives are not supported.
- *
- * Returns: Number of the disk, where the central directory starts.
- */
- deprecated("Multidisk not supported; will be removed in 2.099.0")
- @property @safe @nogc pure nothrow uint diskStartDir() const { return 0; }
-
- /**
* Number of ArchiveMembers in the directory.
*
* Returns: The number of files in this archive.
*/
- deprecated("Use totalEntries instead; will be removed in 2.099.0")
- @property @safe @nogc pure nothrow uint numEntries() const { return cast(uint) _directory.length; }
- @property @safe @nogc pure nothrow uint totalEntries() const { return cast(uint) _directory.length; } /// ditto
+ @property @safe @nogc pure nothrow uint totalEntries() const { return cast(uint) _directory.length; }
/**
* True when the archive is in Zip64 format. Set this to true to force building a Zip64 archive.