summaryrefslogtreecommitdiff
path: root/libphobos
diff options
context:
space:
mode:
authorIain Buclaw <ibuclaw@gdcproject.org>2022-03-13 12:28:05 +0100
committerIain Buclaw <ibuclaw@gdcproject.org>2022-03-13 13:20:02 +0100
commit7e28750395889d16a9cba49cd5935ced7dc00ce8 (patch)
treed2a981788cda569e1a226540c009c09ea1b4ac73 /libphobos
parent1b85638affe6c987a33427c54e0369b819cd7915 (diff)
d: Merge upstream dmd 02a3fafc6, druntime 26b58167, phobos 16cb085b5.
D front-end changes: - Import dmd v2.099.0. - The deprecation period for D1-style operators has ended, any use of the D1 overload operators will now result in a compiler error. - `scope' as a type constraint on class, struct, union, and enum declarations has been deprecated. - Fix segmentation fault when emplacing a new front-end Expression node during CTFE (PR104835). D runtime changes: - Import druntime v2.099.0. - Fix C bindings for stdint types (PR104738). - Fix bus error when allocating new array on the GC (PR104742). - Fix bus error when allocating new pointer on the GC (PR104745). Phobos changes: - Import phobos v2.099.0. - New function `bind' in `std.functional'. gcc/d/ChangeLog: * dmd/MERGE: Merge upstream dmd 02a3fafc6. * dmd/VERSION: Update version to v2.099.0. * imports.cc (ImportVisitor::visit (EnumDeclaration *)): Don't cache decl in front-end AST node. (ImportVisitor::visit (AggregateDeclaration *)): Likewise. (ImportVisitor::visit (ClassDeclaration *)): Likewise. libphobos/ChangeLog: * libdruntime/MERGE: Merge upstream druntime 26b58167. * src/MERGE: Merge upstream phobos 16cb085b5.
Diffstat (limited to 'libphobos')
-rw-r--r--libphobos/libdruntime/MERGE2
-rw-r--r--libphobos/libdruntime/core/internal/gc/bits.d4
-rw-r--r--libphobos/libdruntime/core/stdc/config.d2
-rw-r--r--libphobos/libdruntime/core/stdc/fenv.d2
-rw-r--r--libphobos/libdruntime/core/stdc/stdint.d314
-rw-r--r--libphobos/libdruntime/core/stdcpp/new_.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/stat.d61
-rw-r--r--libphobos/libdruntime/rt/lifetime.d11
-rw-r--r--libphobos/src/MERGE2
-rw-r--r--libphobos/src/std/algorithm/setops.d2
-rw-r--r--libphobos/src/std/bitmanip.d3
-rw-r--r--libphobos/src/std/datetime/interval.d4
-rw-r--r--libphobos/src/std/datetime/systime.d4
-rw-r--r--libphobos/src/std/experimental/allocator/mallocator.d1
-rw-r--r--libphobos/src/std/functional.d165
-rw-r--r--libphobos/src/std/sumtype.d1
-rw-r--r--libphobos/src/std/utf.d12
17 files changed, 505 insertions, 87 deletions
diff --git a/libphobos/libdruntime/MERGE b/libphobos/libdruntime/MERGE
index c4b1538b3a4..77b6ad00173 100644
--- a/libphobos/libdruntime/MERGE
+++ b/libphobos/libdruntime/MERGE
@@ -1,4 +1,4 @@
-0316b981e5f2fa1525e893c5d94c59c847a8c386
+26b581670ef6e2643d74078f200d1cd21fa40e90
The first line of this file holds the git revision number of the last
merge done from the dlang/druntime repository.
diff --git a/libphobos/libdruntime/core/internal/gc/bits.d b/libphobos/libdruntime/core/internal/gc/bits.d
index 3c1bb543460..aa94e407642 100644
--- a/libphobos/libdruntime/core/internal/gc/bits.d
+++ b/libphobos/libdruntime/core/internal/gc/bits.d
@@ -239,7 +239,9 @@ struct GCBits
size_t cntWords = lastWord - firstWord;
copyWordsShifted(firstWord, cntWords, firstOff, source);
- wordtype src = (source[cntWords - 1] >> (BITS_PER_WORD - firstOff)) | (source[cntWords] << firstOff);
+ wordtype src = (source[cntWords - 1] >> (BITS_PER_WORD - firstOff));
+ if (lastOff >= firstOff) // prevent buffer overread
+ src |= (source[cntWords] << firstOff);
wordtype mask = (BITS_2 << lastOff) - 1;
data[lastWord] = (data[lastWord] & ~mask) | (src & mask);
}
diff --git a/libphobos/libdruntime/core/stdc/config.d b/libphobos/libdruntime/core/stdc/config.d
index 44bb7077b59..037af25a675 100644
--- a/libphobos/libdruntime/core/stdc/config.d
+++ b/libphobos/libdruntime/core/stdc/config.d
@@ -34,7 +34,7 @@ version (StdDdoc)
alias ddoc_long = int;
alias ddoc_ulong = uint;
}
- struct ddoc_complex(T) { T re; T im; };
+ struct ddoc_complex(T) { T re; T im; }
}
/***
diff --git a/libphobos/libdruntime/core/stdc/fenv.d b/libphobos/libdruntime/core/stdc/fenv.d
index 3002c022613..88123fb16a6 100644
--- a/libphobos/libdruntime/core/stdc/fenv.d
+++ b/libphobos/libdruntime/core/stdc/fenv.d
@@ -151,6 +151,8 @@ version (GNUFP)
// https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/sparc/fpu/bits/fenv.h
else version (SPARC_Any)
{
+ import core.stdc.config : c_ulong;
+
alias fenv_t = c_ulong;
alias fexcept_t = c_ulong;
}
diff --git a/libphobos/libdruntime/core/stdc/stdint.d b/libphobos/libdruntime/core/stdc/stdint.d
index 9db2fdaa691..556ac019eeb 100644
--- a/libphobos/libdruntime/core/stdc/stdint.d
+++ b/libphobos/libdruntime/core/stdc/stdint.d
@@ -36,20 +36,7 @@ extern (C):
nothrow:
@nogc:
-// These are defined the same way as D basic types, so the definition is
-// platform-independant
-alias int8_t = byte; ///
-alias int16_t = short; ///
-alias uint8_t = ubyte; ///
-alias uint16_t = ushort; ///
-
-// 32 bit types and need to be defined on-platform basis, because
-// they might have C++ binary mangling of `int` or `long`.
-// 64-bit types respectively might be mangled as `long` or `long long`
-
-// It would seem correct to define intmax_t and uintmax_t here, but C and C++
-// compilers don't in practice always set them to the maximum supported value.
-// See https://quuxplusone.github.io/blog/2019/02/28/is-int128-integral/
+
static if (is(ucent))
{
alias int128_t = cent; ///
@@ -58,6 +45,10 @@ static if (is(ucent))
version (Windows)
{
+ alias int8_t = byte; ///
+ alias int16_t = short; ///
+ alias uint8_t = ubyte; ///
+ alias uint16_t = ushort; ///
version (CRuntime_DigitalMars)
{
alias int32_t = cpp_long; ///
@@ -71,23 +62,31 @@ version (Windows)
alias int64_t = long; ///
alias uint64_t = ulong; ///
- alias int_least8_t = byte; ///
- alias uint_least8_t = ubyte; ///
- alias int_least16_t = short; ///
- alias uint_least16_t = ushort; ///
- alias int_least32_t = int32_t; ///
+ alias int_least8_t = byte; ///
+ alias uint_least8_t = ubyte; ///
+ alias int_least16_t = short; ///
+ alias uint_least16_t = ushort; ///
+ alias int_least32_t = int32_t; ///
alias uint_least32_t = uint32_t; ///
- alias int_least64_t = long; ///
- alias uint_least64_t = ulong; ///
+ alias int_least64_t = long; ///
+ alias uint_least64_t = ulong; ///
- alias int_fast8_t = byte; ///
- alias uint_fast8_t = ubyte; ///
- alias int_fast16_t = int; ///
- alias uint_fast16_t = uint; ///
- alias int_fast32_t = int32_t; ///
+ alias int_fast8_t = byte; ///
+ alias uint_fast8_t = ubyte; ///
+ version (MinGW)
+ {
+ alias int_fast16_t = short; ///
+ alias uint_fast16_t = ushort; ///
+ }
+ else
+ {
+ alias int_fast16_t = int; ///
+ alias uint_fast16_t = uint; ///
+ }
+ alias int_fast32_t = int32_t; ///
alias uint_fast32_t = uint32_t; ///
- alias int_fast64_t = long; ///
- alias uint_fast64_t = ulong; ///
+ alias int_fast64_t = long; ///
+ alias uint_fast64_t = ulong; ///
alias intptr_t = ptrdiff_t; ///
alias uintptr_t = size_t; ///
@@ -96,6 +95,10 @@ version (Windows)
}
else version (Darwin)
{
+ alias int8_t = byte; ///
+ alias int16_t = short; ///
+ alias uint8_t = ubyte; ///
+ alias uint16_t = ushort; ///
alias int32_t = int; ///
alias uint32_t = uint; ///
alias int64_t = cpp_longlong; ///
@@ -124,32 +127,27 @@ else version (Darwin)
alias intmax_t = long; ///
alias uintmax_t = ulong; ///
}
-else version (Posix)
+else version (linux)
{
- alias int32_t = int; ///
- alias uint32_t = uint; ///
- alias int64_t = long; ///
- alias uint64_t = ulong; ///
-
- alias int_least8_t = byte; ///
- alias uint_least8_t = ubyte; ///
- alias int_least16_t = short; ///
+ alias int8_t = byte; ///
+ alias int16_t = short; ///
+ alias uint8_t = ubyte; ///
+ alias uint16_t = ushort; ///
+ alias int32_t = int; ///
+ alias uint32_t = uint; ///
+ alias int64_t = long; ///
+ alias uint64_t = ulong; ///
+
+ alias int_least8_t = byte; ///
+ alias uint_least8_t = ubyte; ///
+ alias int_least16_t = short; ///
alias uint_least16_t = ushort; ///
- alias int_least32_t = int; ///
- alias uint_least32_t = uint; ///
- alias int_least64_t = long; ///
- alias uint_least64_t = ulong;///
+ alias int_least32_t = int; ///
+ alias uint_least32_t = uint; ///
+ alias int_least64_t = long; ///
+ alias uint_least64_t = ulong; ///
- version (FreeBSD)
- {
- alias int_fast8_t = int; ///
- alias uint_fast8_t = uint; ///
- alias int_fast16_t = int; ///
- alias uint_fast16_t = uint; ///
- alias int_fast32_t = int; ///
- alias uint_fast32_t = uint; ///
- }
- else version (CRuntime_Musl)
+ version (CRuntime_Musl)
{
alias int_fast8_t = byte; ///
alias uint_fast8_t = ubyte; ///
@@ -167,17 +165,221 @@ else version (Posix)
alias int_fast32_t = ptrdiff_t; ///
alias uint_fast32_t = size_t; ///
}
- alias int_fast64_t = long; ///
+ alias int_fast64_t = long; ///
+ alias uint_fast64_t = ulong; ///
+
+ alias intptr_t = ptrdiff_t; ///
+ alias uintptr_t = size_t; ///
+ alias intmax_t = long; ///
+ alias uintmax_t = ulong; ///
+}
+else version (CRuntime_Glibc)
+{
+ alias int8_t = byte; ///
+ alias int16_t = short; ///
+ alias uint8_t = ubyte; ///
+ alias uint16_t = ushort; ///
+ alias int32_t = int; ///
+ alias uint32_t = uint; ///
+ alias int64_t = long; ///
+ alias uint64_t = ulong; ///
+
+ alias int_least8_t = byte; ///
+ alias uint_least8_t = ubyte; ///
+ alias int_least16_t = short; ///
+ alias uint_least16_t = ushort; ///
+ alias int_least32_t = int; ///
+ alias uint_least32_t = uint; ///
+ alias int_least64_t = long; ///
+ alias uint_least64_t = ulong; ///
+
+ alias int_fast8_t = byte; ///
+ alias uint_fast8_t = ubyte; ///
+ alias int_fast16_t = ptrdiff_t; ///
+ alias uint_fast16_t = size_t; ///
+ alias int_fast32_t = ptrdiff_t; ///
+ alias uint_fast32_t = size_t; ///
+ alias int_fast64_t = long; ///
+ alias uint_fast64_t = ulong; ///
+
+ alias intptr_t = ptrdiff_t; ///
+ alias uintptr_t = size_t; ///
+ alias intmax_t = long; ///
+ alias uintmax_t = ulong; ///
+}
+else version (DragonFlyBSD)
+{
+ alias int8_t = byte; ///
+ alias int16_t = short; ///
+ alias uint8_t = ubyte; ///
+ alias uint16_t = ushort; ///
+ alias int32_t = int; ///
+ alias uint32_t = uint; ///
+ alias int64_t = long; ///
+ alias uint64_t = ulong; ///
+
+ alias int_least8_t = int8_t; ///
+ alias uint_least8_t = uint8_t; ///
+ alias int_least16_t = int16_t; ///
+ alias uint_least16_t = uint16_t; ///
+ alias int_least32_t = int32_t; ///
+ alias uint_least32_t = uint32_t; ///
+ alias int_least64_t = int64_t; ///
+ alias uint_least64_t = uint64_t; ///
+
+ alias int_fast8_t = int32_t; ///
+ alias uint_fast8_t = uint32_t; ///
+ alias int_fast16_t = int32_t; ///
+ alias uint_fast16_t = uint32_t; ///
+ alias int_fast32_t = int32_t; ///
+ alias uint_fast32_t = uint32_t; ///
+ alias int_fast64_t = int64_t; ///
+ alias uint_fast64_t = uint64_t; ///
+
+ alias intptr_t = ptrdiff_t; ///
+ alias uintptr_t = size_t; ///
+ alias intmax_t = long; ///
+ alias uintmax_t = ulong; ///
+}
+else version (FreeBSD)
+{
+ alias int8_t = byte; ///
+ alias int16_t = short; ///
+ alias uint8_t = ubyte; ///
+ alias uint16_t = ushort; ///
+ alias int32_t = int; ///
+ alias uint32_t = uint; ///
+ alias int64_t = long; ///
+ alias uint64_t = ulong; ///
+
+ alias int_least8_t = byte; ///
+ alias uint_least8_t = ubyte; ///
+ alias int_least16_t = short; ///
+ alias uint_least16_t = ushort; ///
+ alias int_least32_t = int; ///
+ alias uint_least32_t = uint; ///
+ alias int_least64_t = long; ///
+ alias uint_least64_t = ulong; ///
+
+ alias int_fast8_t = int; ///
+ alias uint_fast8_t = uint; ///
+ alias int_fast16_t = int; ///
+ alias uint_fast16_t = uint; ///
+ alias int_fast32_t = int; ///
+ alias uint_fast32_t = uint; ///
+ alias int_fast64_t = long; ///
alias uint_fast64_t = ulong; ///
alias intptr_t = ptrdiff_t; ///
- alias uintptr_t = size_t; ///
- alias intmax_t = long; ///
- alias uintmax_t = ulong; ///
+ alias uintptr_t = size_t; ///
+ alias intmax_t = long; ///
+ alias uintmax_t = ulong; ///
+}
+else version (NetBSD)
+{
+ alias int8_t = byte; ///
+ alias int16_t = short; ///
+ alias uint8_t = ubyte; ///
+ alias uint16_t = ushort; ///
+ alias int32_t = int; ///
+ alias uint32_t = uint; ///
+ alias int64_t = long; ///
+ alias uint64_t = ulong; ///
+
+ alias int_least8_t = int8_t; ///
+ alias uint_least8_t = uint8_t; ///
+ alias int_least16_t = int16_t; ///
+ alias uint_least16_t = uint16_t; ///
+ alias int_least32_t = int32_t; ///
+ alias uint_least32_t = uint32_t; ///
+ alias int_least64_t = int64_t; ///
+ alias uint_least64_t = uint64_t; ///
+
+ alias int_fast8_t = int32_t; ///
+ alias uint_fast8_t = uint32_t; ///
+ alias int_fast16_t = int32_t; ///
+ alias uint_fast16_t = uint32_t; ///
+ alias int_fast32_t = int32_t; ///
+ alias uint_fast32_t = uint32_t; ///
+ alias int_fast64_t = int64_t; ///
+ alias uint_fast64_t = uint64_t; ///
+
+ alias intptr_t = ptrdiff_t; ///
+ alias uintptr_t = size_t; ///
+ alias intmax_t = long; ///
+ alias uintmax_t = ulong; ///
+}
+else version (OpenBSD)
+{
+ alias int8_t = byte; ///
+ alias int16_t = short; ///
+ alias uint8_t = ubyte; ///
+ alias uint16_t = ushort; ///
+ alias int32_t = int; ///
+ alias uint32_t = uint; ///
+ alias int64_t = cpp_longlong; ///
+ alias uint64_t = cpp_ulonglong; ///
+
+ alias int_least8_t = byte; ///
+ alias uint_least8_t = ubyte; ///
+ alias int_least16_t = short; ///
+ alias uint_least16_t = ushort; ///
+ alias int_least32_t = int; ///
+ alias uint_least32_t = uint; ///
+ alias int_least64_t = cpp_longlong; ///
+ alias uint_least64_t = cpp_ulonglong; ///
+
+ alias int_fast8_t = int; ///
+ alias uint_fast8_t = uint; ///
+ alias int_fast16_t = int; ///
+ alias uint_fast16_t = uint; ///
+ alias int_fast32_t = int; ///
+ alias uint_fast32_t = uint; ///
+ alias int_fast64_t = cpp_longlong; ///
+ alias uint_fast64_t = cpp_ulonglong; ///
+
+ alias intptr_t = cpp_long; ///
+ alias uintptr_t = cpp_ulong; ///
+ alias intmax_t = cpp_longlong; ///
+ alias uintmax_t = cpp_ulonglong; ///
+}
+else version (Solaris)
+{
+ alias int8_t = char; ///
+ alias int16_t = short; ///
+ alias uint8_t = ubyte; ///
+ alias uint16_t = ushort; ///
+ alias int32_t = int; ///
+ alias uint32_t = uint; ///
+ alias int64_t = long; ///
+ alias uint64_t = ulong; ///
+
+ alias int_least8_t = char; ///
+ alias uint_least8_t = ubyte; ///
+ alias int_least16_t = short; ///
+ alias uint_least16_t = ushort; ///
+ alias int_least32_t = int; ///
+ alias uint_least32_t = uint; ///
+ alias int_least64_t = long; ///
+ alias uint_least64_t = ulong; ///
+
+ alias int_fast8_t = char; ///
+ alias uint_fast8_t = ubyte; ///
+ alias int_fast16_t = int; ///
+ alias uint_fast16_t = uint; ///
+ alias int_fast32_t = int; ///
+ alias uint_fast32_t = uint; ///
+ alias int_fast64_t = long; ///
+ alias uint_fast64_t = ulong; ///
+
+ alias intptr_t = ptrdiff_t; ///
+ alias uintptr_t = size_t; ///
+ alias intmax_t = long; ///
+ alias uintmax_t = ulong; ///
}
else
{
- static assert(0);
+ static assert(false, "Unsupported architecture.");
}
diff --git a/libphobos/libdruntime/core/stdcpp/new_.d b/libphobos/libdruntime/core/stdcpp/new_.d
index 77c179ce962..6a598baec28 100644
--- a/libphobos/libdruntime/core/stdcpp/new_.d
+++ b/libphobos/libdruntime/core/stdcpp/new_.d
@@ -26,7 +26,7 @@ extern (C++, "std")
struct nothrow_t {}
///
- enum align_val_t : size_t { defaultAlignment = __STDCPP_DEFAULT_NEW_ALIGNMENT__ };
+ enum align_val_t : size_t { defaultAlignment = __STDCPP_DEFAULT_NEW_ALIGNMENT__ }
///
class bad_alloc : exception
diff --git a/libphobos/libdruntime/core/sys/windows/stat.d b/libphobos/libdruntime/core/sys/windows/stat.d
index c9ee6ce5ca8..16f66e1287e 100644
--- a/libphobos/libdruntime/core/sys/windows/stat.d
+++ b/libphobos/libdruntime/core/sys/windows/stat.d
@@ -8,6 +8,8 @@ version (Windows):
extern (C) nothrow @nogc:
@system:
+import core.sys.windows.stdc.time;
+
// Posix version is in core.sys.posix.sys.stat
enum S_IFMT = 0xF000;
@@ -30,22 +32,49 @@ int S_ISDIR(int m) { return (m & S_IFMT) == S_IFDIR; }
int S_ISCHR(int m) { return (m & S_IFMT) == S_IFCHR; }
}
-struct struct_stat
+version (CRuntime_DigitalMars)
{
- short st_dev;
- ushort st_ino;
- ushort st_mode;
- short st_nlink;
- ushort st_uid;
- ushort st_gid;
- short st_rdev;
- short dummy;
- int st_size;
- int st_atime;
- int st_mtime;
- int st_ctime;
+ struct struct_stat
+ {
+ short st_dev;
+ ushort st_ino;
+ ushort st_mode;
+ short st_nlink;
+ ushort st_uid;
+ ushort st_gid;
+ short st_rdev;
+ short dummy;
+ int st_size;
+ time_t st_atime;
+ time_t st_mtime;
+ time_t st_ctime;
+ }
+
+ int stat(const(char)*, struct_stat *);
+ int fstat(int, struct_stat *) @trusted;
+ int _wstat(const(wchar)*, struct_stat *);
}
+else version (CRuntime_Microsoft)
+{
+ struct struct_stat
+ {
+ uint st_dev;
+ ushort st_ino;
+ ushort st_mode;
+ short st_nlink;
+ short st_uid;
+ short st_gid;
+ uint st_rdev;
+ int st_size;
+ time_t st_atime;
+ time_t st_mtime;
+ time_t st_ctime;
+ }
-int stat(const(char)*, struct_stat *);
-int fstat(int, struct_stat *) @trusted;
-int _wstat(const(wchar)*, struct_stat *);
+ // These assume time_t is 32 bits (which druntime's definition currently is)
+ // Add pragma(mangle) to use _stat64 etc. when time_t is made 64-bit
+ // See also: https://issues.dlang.org/show_bug.cgi?id=21134
+ int stat(const(char)*, struct_stat *);
+ int fstat(int, struct_stat *) @trusted;
+ int _wstat(const(wchar)*, struct_stat *);
+}
diff --git a/libphobos/libdruntime/rt/lifetime.d b/libphobos/libdruntime/rt/lifetime.d
index 1f7a81de80f..b0e25b57054 100644
--- a/libphobos/libdruntime/rt/lifetime.d
+++ b/libphobos/libdruntime/rt/lifetime.d
@@ -1011,8 +1011,12 @@ extern (C) void[] _d_newarrayiT(const TypeInfo ti, size_t length) pure nothrow @
foreach (T; AliasSeq!(ubyte, ushort, uint, ulong))
{
case T.sizeof:
- (cast(T*)result.ptr)[0 .. size * length / T.sizeof] = *cast(T*)init.ptr;
- return result;
+ if (tinext.talign % T.alignof == 0)
+ {
+ (cast(T*)result.ptr)[0 .. size * length / T.sizeof] = *cast(T*)init.ptr;
+ return result;
+ }
+ goto default;
}
default:
@@ -1118,7 +1122,8 @@ extern (C) void* _d_newitemU(scope const TypeInfo _ti) pure nothrow @weak
if (tiSize)
{
- *cast(TypeInfo*)(p + itemSize) = null; // the GC might not have cleared this area
+ // the GC might not have cleared the padding area in the block
+ *cast(TypeInfo*)(p + (itemSize & ~(size_t.sizeof - 1))) = null;
*cast(TypeInfo*)(p + blkInf.size - tiSize) = cast() ti;
}
diff --git a/libphobos/src/MERGE b/libphobos/src/MERGE
index 5fd357c534a..963ffe020de 100644
--- a/libphobos/src/MERGE
+++ b/libphobos/src/MERGE
@@ -1,4 +1,4 @@
-a1f8c4c0700ce4e256f4130ad7883c6ea3890901
+16cb085b584f100fa677e2e64ff6b6dbb4921ad1
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/setops.d b/libphobos/src/std/algorithm/setops.d
index ede1831028e..cc6f5b77db7 100644
--- a/libphobos/src/std/algorithm/setops.d
+++ b/libphobos/src/std/algorithm/setops.d
@@ -404,7 +404,7 @@ if (ranges.length >= 2 &&
r = ranges[i].save; // rollover
}
}
- @property Result save() scope return
+ @property Result save() return scope
{
Result copy = this;
foreach (i, r; ranges)
diff --git a/libphobos/src/std/bitmanip.d b/libphobos/src/std/bitmanip.d
index 9af9d721230..de2e0fb262f 100644
--- a/libphobos/src/std/bitmanip.d
+++ b/libphobos/src/std/bitmanip.d
@@ -1447,7 +1447,8 @@ public:
size_t bitCount;
foreach (i; 0 .. fullWords)
bitCount += countBitsSet(_ptr[i]);
- bitCount += countBitsSet(_ptr[fullWords] & endMask);
+ if (endBits)
+ bitCount += countBitsSet(_ptr[fullWords] & endMask);
return bitCount;
}
else
diff --git a/libphobos/src/std/datetime/interval.d b/libphobos/src/std/datetime/interval.d
index ba2a21056c7..d787e3a8080 100644
--- a/libphobos/src/std/datetime/interval.d
+++ b/libphobos/src/std/datetime/interval.d
@@ -7848,12 +7848,12 @@ if (isTimePoint!TP &&
duration = The duration which separates each successive time point in
the range.
+/
-TP delegate(scope const TP) everyDuration(TP, Direction dir = Direction.fwd, D)(D duration) nothrow
+TP delegate(return scope const TP) everyDuration(TP, Direction dir = Direction.fwd, D)(D duration) nothrow
if (isTimePoint!TP &&
__traits(compiles, TP.init + duration) &&
(dir == Direction.fwd || dir == Direction.bwd))
{
- TP func(scope const TP tp)
+ TP func(return scope const TP tp)
{
static if (dir == Direction.fwd)
return tp + duration;
diff --git a/libphobos/src/std/datetime/systime.d b/libphobos/src/std/datetime/systime.d
index db325f727e8..949ad7d75cc 100644
--- a/libphobos/src/std/datetime/systime.d
+++ b/libphobos/src/std/datetime/systime.d
@@ -6269,7 +6269,7 @@ public:
duration = The $(REF Duration, core,time) to add to or subtract from
this $(LREF SysTime).
+/
- SysTime opBinary(string op)(Duration duration) @safe const pure nothrow scope
+ SysTime opBinary(string op)(Duration duration) @safe const pure nothrow return scope
if (op == "+" || op == "-")
{
SysTime retval = SysTime(this._stdTime, this._timezone);
@@ -7668,7 +7668,7 @@ public:
$(LREF SysTime) for the last day in the month that this Date is in.
The time portion of endOfMonth is always 23:59:59.9999999.
+/
- @property SysTime endOfMonth() @safe const nothrow scope
+ @property SysTime endOfMonth() @safe const nothrow return scope
{
immutable hnsecs = adjTime;
immutable days = getUnitsFromHNSecs!"days"(hnsecs);
diff --git a/libphobos/src/std/experimental/allocator/mallocator.d b/libphobos/src/std/experimental/allocator/mallocator.d
index 895d5883f52..de9afbbf7d5 100644
--- a/libphobos/src/std/experimental/allocator/mallocator.d
+++ b/libphobos/src/std/experimental/allocator/mallocator.d
@@ -392,6 +392,7 @@ version (Posix)
AlignedMallocator.instance.alignedReallocate(c, 32, 32);
assert(c.ptr);
+ version (LDC_AddressSanitizer) {} else // AddressSanitizer does not support such large memory allocations (0x10000000000 max)
version (DragonFlyBSD) {} else /* FIXME: Malloc on DragonFly does not return NULL when allocating more than UINTPTR_MAX
* $(LINK: https://bugs.dragonflybsd.org/issues/3114, dragonfly bug report)
* $(LINK: https://github.com/dlang/druntime/pull/1999#discussion_r157536030, PR Discussion) */
diff --git a/libphobos/src/std/functional.d b/libphobos/src/std/functional.d
index da698e045fe..90b0f91ecce 100644
--- a/libphobos/src/std/functional.d
+++ b/libphobos/src/std/functional.d
@@ -1847,3 +1847,168 @@ if (isCallable!(F))
static assert(! is(typeof(dg_xtrnC) == typeof(dg_xtrnD)));
}
}
+
+// Converts an unsigned integer to a compile-time string constant.
+private enum toCtString(ulong n) = n.stringof[0 .. $ - "LU".length];
+
+// Check that .stringof does what we expect, since it's not guaranteed by the
+// language spec.
+@safe unittest
+{
+ assert(toCtString!0 == "0");
+ assert(toCtString!123456 == "123456");
+}
+
+/**
+ * Passes the fields of a struct as arguments to a function.
+ *
+ * Can be used with a $(LINK2 https://dlang.org/spec/expression.html#function_literals,
+ * function literal) to give temporary names to the fields of a struct or
+ * tuple.
+ *
+ * Params:
+ * fun = Callable that the struct's fields will be passed to.
+ *
+ * Returns:
+ * A function that accepts a single struct as an argument and passes its
+ * fields to `fun` when called.
+ */
+template bind(alias fun)
+{
+ /**
+ * Params:
+ * args = The struct or tuple whose fields will be used as arguments.
+ *
+ * Returns: `fun(args.tupleof)`
+ */
+ auto ref bind(T)(auto ref T args)
+ if (is(T == struct))
+ {
+ import std.meta : Map = staticMap;
+ import core.lifetime : move;
+
+ // Forwards the i'th member of `args`
+ // Needed because core.lifetime.forward doesn't work on struct members
+ template forwardArg(size_t i)
+ {
+ static if (__traits(isRef, args) || !is(typeof(move(args.tupleof[i]))))
+ enum forwardArg = "args.tupleof[" ~ toCtString!i ~ "], ";
+ else
+ enum forwardArg = "move(args.tupleof[" ~ toCtString!i ~ "]), ";
+ }
+
+ static if (args.tupleof.length == 0)
+ enum argList = "";
+ else
+ alias argList = Map!(forwardArg, Iota!(args.tupleof.length));
+
+ return mixin("fun(", argList, ")");
+ }
+}
+
+/// Giving names to tuple elements
+@safe unittest
+{
+ import std.typecons : tuple;
+
+ auto name = tuple("John", "Doe");
+ string full = name.bind!((first, last) => first ~ " " ~ last);
+ assert(full == "John Doe");
+}
+
+/// Passing struct fields to a function
+@safe unittest
+{
+ import std.algorithm.comparison : min, max;
+
+ struct Pair
+ {
+ int a;
+ int b;
+ }
+
+ auto p = Pair(123, 456);
+ assert(p.bind!min == 123); // min(p.a, p.b)
+ assert(p.bind!max == 456); // max(p.a, p.b)
+}
+
+/// In a range pipeline
+@safe unittest
+{
+ import std.algorithm.iteration : map, filter;
+ import std.algorithm.comparison : equal;
+ import std.typecons : tuple;
+
+ auto ages = [
+ tuple("Alice", 35),
+ tuple("Bob", 64),
+ tuple("Carol", 21),
+ tuple("David", 39),
+ tuple("Eve", 50)
+ ];
+
+ auto overForty = ages
+ .filter!(bind!((name, age) => age > 40))
+ .map!(bind!((name, age) => name));
+
+ assert(overForty.equal(["Bob", "Eve"]));
+}
+
+// Zero arguments
+@safe unittest
+{
+ struct Empty {}
+
+ assert(Empty().bind!(() => 123) == 123);
+}
+
+// Non-copyable arguments
+@safe unittest
+{
+ import std.typecons : tuple;
+
+ static struct NoCopy
+ {
+ int n;
+ @disable this(this);
+ }
+
+ static struct Pair
+ {
+ NoCopy a, b;
+ }
+
+ static auto fun(NoCopy a, NoCopy b)
+ {
+ return tuple(a.n, b.n);
+ }
+
+ auto expected = fun(NoCopy(1), NoCopy(2));
+ assert(Pair(NoCopy(1), NoCopy(2)).bind!fun == expected);
+}
+
+// ref arguments
+@safe unittest
+{
+ import std.typecons : tuple;
+
+ auto t = tuple(123, 456);
+ t.bind!((ref int a, int b) { a = 789; b = 1011; });
+
+ assert(t[0] == 789);
+ assert(t[1] == 456);
+}
+
+// auto ref arguments
+@safe unittest
+{
+ import std.typecons : tuple;
+
+ auto t = tuple(123);
+ t.bind!((auto ref x) {
+ static assert(__traits(isRef, x));
+ });
+ tuple(123).bind!((auto ref x) {
+ static assert(!__traits(isRef, x));
+ });
+}
diff --git a/libphobos/src/std/sumtype.d b/libphobos/src/std/sumtype.d
index 3833c84243c..8da38bdb4e6 100644
--- a/libphobos/src/std/sumtype.d
+++ b/libphobos/src/std/sumtype.d
@@ -13,6 +13,7 @@ include:
License: Boost License 1.0
Authors: Paul Backus
+Source: $(PHOBOSSRC std/sumtype.d)
+/
module std.sumtype;
diff --git a/libphobos/src/std/utf.d b/libphobos/src/std/utf.d
index 5c23684b9ae..f0200ce7052 100644
--- a/libphobos/src/std/utf.d
+++ b/libphobos/src/std/utf.d
@@ -1209,6 +1209,15 @@ do
assert("ë"w.decode(i) == 'ë' && i == 1);
}
+@safe pure unittest // https://issues.dlang.org/show_bug.cgi?id=22867
+{
+ import std.conv : hexString;
+ string data = hexString!"f787a598";
+ size_t offset = 0;
+ try data.decode(offset);
+ catch (UTFException ex) assert(offset == 0);
+}
+
/++
`decodeFront` is a variant of $(LREF decode) which specifically decodes
the first code point. Unlike $(LREF decode), `decodeFront` accepts any
@@ -1671,7 +1680,6 @@ if (
}
}
- index += i + 1;
static if (i == 3)
{
if (d > dchar.max)
@@ -1682,6 +1690,8 @@ if (
throw invalidUTF();
}
}
+
+ index += i + 1;
return d;
}
}