diff options
author | Iain Buclaw <ibuclaw@gdcproject.org> | 2022-03-13 12:28:05 +0100 |
---|---|---|
committer | Iain Buclaw <ibuclaw@gdcproject.org> | 2022-03-13 13:20:02 +0100 |
commit | 7e28750395889d16a9cba49cd5935ced7dc00ce8 (patch) | |
tree | d2a981788cda569e1a226540c009c09ea1b4ac73 /libphobos | |
parent | 1b85638affe6c987a33427c54e0369b819cd7915 (diff) | |
download | gcc-7e28750395889d16a9cba49cd5935ced7dc00ce8.zip gcc-7e28750395889d16a9cba49cd5935ced7dc00ce8.tar.gz gcc-7e28750395889d16a9cba49cd5935ced7dc00ce8.tar.bz2 |
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/MERGE | 2 | ||||
-rw-r--r-- | libphobos/libdruntime/core/internal/gc/bits.d | 4 | ||||
-rw-r--r-- | libphobos/libdruntime/core/stdc/config.d | 2 | ||||
-rw-r--r-- | libphobos/libdruntime/core/stdc/fenv.d | 2 | ||||
-rw-r--r-- | libphobos/libdruntime/core/stdc/stdint.d | 314 | ||||
-rw-r--r-- | libphobos/libdruntime/core/stdcpp/new_.d | 2 | ||||
-rw-r--r-- | libphobos/libdruntime/core/sys/windows/stat.d | 61 | ||||
-rw-r--r-- | libphobos/libdruntime/rt/lifetime.d | 11 | ||||
-rw-r--r-- | libphobos/src/MERGE | 2 | ||||
-rw-r--r-- | libphobos/src/std/algorithm/setops.d | 2 | ||||
-rw-r--r-- | libphobos/src/std/bitmanip.d | 3 | ||||
-rw-r--r-- | libphobos/src/std/datetime/interval.d | 4 | ||||
-rw-r--r-- | libphobos/src/std/datetime/systime.d | 4 | ||||
-rw-r--r-- | libphobos/src/std/experimental/allocator/mallocator.d | 1 | ||||
-rw-r--r-- | libphobos/src/std/functional.d | 165 | ||||
-rw-r--r-- | libphobos/src/std/sumtype.d | 1 | ||||
-rw-r--r-- | libphobos/src/std/utf.d | 12 |
17 files changed, 505 insertions, 87 deletions
diff --git a/libphobos/libdruntime/MERGE b/libphobos/libdruntime/MERGE index c4b1538..77b6ad0 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 3c1bb54..aa94e40 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 44bb707..037af25 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 3002c02..88123fb 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 9db2fda..556ac01 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 77c179c..6a598ba 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 c9ee6ce..16f66e1 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 1f7a81d..b0e25b5 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 5fd357c..963ffe0 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 ede1831..cc6f5b7 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 9af9d72..de2e0fb 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 ba2a210..d787e3a 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 db325f7..949ad7d 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 895d588..de9afbb 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 da698e0..90b0f91 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 3833c84..8da38bd 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 5c23684..f0200ce 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; } } |