diff options
Diffstat (limited to 'libphobos/src')
-rw-r--r-- | libphobos/src/MERGE | 2 | ||||
-rw-r--r-- | libphobos/src/std/algorithm/iteration.d | 52 | ||||
-rw-r--r-- | libphobos/src/std/algorithm/mutation.d | 29 | ||||
-rw-r--r-- | libphobos/src/std/algorithm/sorting.d | 26 | ||||
-rw-r--r-- | libphobos/src/std/concurrency.d | 32 | ||||
-rw-r--r-- | libphobos/src/std/container/dlist.d | 6 | ||||
-rw-r--r-- | libphobos/src/std/container/rbtree.d | 2 | ||||
-rw-r--r-- | libphobos/src/std/datetime/interval.d | 6 | ||||
-rw-r--r-- | libphobos/src/std/datetime/systime.d | 27 | ||||
-rw-r--r-- | libphobos/src/std/datetime/timezone.d | 74 | ||||
-rw-r--r-- | libphobos/src/std/file.d | 28 | ||||
-rw-r--r-- | libphobos/src/std/internal/cstring.d | 2 | ||||
-rw-r--r-- | libphobos/src/std/internal/math/biguintcore.d | 12 | ||||
-rw-r--r-- | libphobos/src/std/json.d | 10 | ||||
-rw-r--r-- | libphobos/src/std/net/isemail.d | 2 | ||||
-rw-r--r-- | libphobos/src/std/process.d | 4 | ||||
-rw-r--r-- | libphobos/src/std/random.d | 12 | ||||
-rw-r--r-- | libphobos/src/std/stdio.d | 2 | ||||
-rw-r--r-- | libphobos/src/std/typecons.d | 35 | ||||
-rw-r--r-- | libphobos/src/std/uni/package.d | 4 | ||||
-rw-r--r-- | libphobos/src/std/utf.d | 12 |
21 files changed, 224 insertions, 155 deletions
diff --git a/libphobos/src/MERGE b/libphobos/src/MERGE index 29bcf33..68fefcb 100644 --- a/libphobos/src/MERGE +++ b/libphobos/src/MERGE @@ -1,4 +1,4 @@ -574bf883b790340fb753d6542ec48a3ba3e6cb82 +12329adb67fb43891d6e4e543e7257bc34db0aa7 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/iteration.d b/libphobos/src/std/algorithm/iteration.d index 9e728e4..af665c4 100644 --- a/libphobos/src/std/algorithm/iteration.d +++ b/libphobos/src/std/algorithm/iteration.d @@ -3595,7 +3595,6 @@ if (isInputRange!RoR && isInputRange!(ElementType!RoR) assert(res.equal("cba")); } - /// Ditto auto joiner(RoR)(RoR r) if (isInputRange!RoR && isInputRange!(ElementType!RoR)) @@ -3621,14 +3620,32 @@ if (isInputRange!RoR && isInputRange!(ElementType!RoR)) _currentBack = typeof(_currentBack).init; } + void replaceCurrent(typeof(_current) current) @trusted + { + import core.lifetime : move; + + current.move(_current); + } + + static if (isBidirectional) + { + void replaceCurrentBack(typeof(_currentBack) currentBack) @trusted + { + import core.lifetime : move; + + currentBack.move(_currentBack); + } + } + public: this(RoR r) { _items = r; + // field _current must be initialized in constructor, because it is nested struct + _current = typeof(_current).init; static if (isBidirectional && hasNested!Result) _currentBack = typeof(_currentBack).init; - // field _current must be initialized in constructor, because it is nested struct mixin(popFrontEmptyElements); static if (isBidirectional) mixin(popBackEmptyElements); @@ -3673,13 +3690,13 @@ if (isInputRange!RoR && isInputRange!(ElementType!RoR)) // consumed when a .save'd copy of ourselves is iterated over. So // we need to .save each subrange we traverse. static if (isForwardRange!RoR && isForwardRange!(ElementType!RoR)) - _current = _items.front.save; + replaceCurrent(_items.front.save); else - _current = _items.front; + replaceCurrent(_items.front); } else { - _current = typeof(_current).init; + replaceCurrent(typeof(_current).init); } }; @@ -3696,9 +3713,9 @@ if (isInputRange!RoR && isInputRange!(ElementType!RoR)) static if (isBidirectional) { static if (is(typeof(null) : typeof(_currentBack))) - r._currentBack = _currentBack is null ? null : _currentBack.save; + r.replaceCurrentBack(_currentBack is null ? null : _currentBack.save); else - r._currentBack = _currentBack.save; + r.replaceCurrentBack(_currentBack.save); r.reachedFinalElement = reachedFinalElement; } return r; @@ -3784,22 +3801,22 @@ if (isInputRange!RoR && isInputRange!(ElementType!RoR)) static if (isForwardRange!RoR && isForwardRange!(ElementType!RoR)) { if (reachedFinalElement) - _current = _items.back.save; + replaceCurrent(_items.back.save); else - _currentBack = _items.back.save; + replaceCurrentBack(_items.back.save); } else { if (reachedFinalElement) - _current = _items.back; + replaceCurrent(_items.back); else - _currentBack = _items.back; + replaceCurrentBack(_items.back); } } else { - _current = typeof(_current).init; - _currentBack = typeof(_currentBack).init; + replaceCurrent(typeof(_current).init); + replaceCurrentBack(typeof(_currentBack).init); } }; @@ -4232,6 +4249,15 @@ if (isInputRange!RoR && isInputRange!(ElementType!RoR)) assert([[0]].joiner.save.back == 0); } +// https://issues.dlang.org/show_bug.cgi?id=22561 +@safe pure unittest +{ + import std.range : only; + + static immutable struct S { int[] array; } + assert([only(S(null))].joiner.front == S(null)); +} + /++ Implements the homonym function (also known as `accumulate`, $(D compress), `inject`, or `foldl`) present in various programming diff --git a/libphobos/src/std/algorithm/mutation.d b/libphobos/src/std/algorithm/mutation.d index 07cbb9b..22b7b98 100644 --- a/libphobos/src/std/algorithm/mutation.d +++ b/libphobos/src/std/algorithm/mutation.d @@ -886,31 +886,13 @@ if (isInputRange!Range && hasLvalueElements!Range && hasAssignableElements!Range static if (hasElaborateAssign!T) { import std.algorithm.internal : addressOf; - //Elaborate opAssign. Must go the memcpy road. - //We avoid calling emplace here, because our goal is to initialize to - //the static state of T.init, - //So we want to avoid any un-necassarilly CC'ing of T.init + //Elaborate opAssign. Must go the memcpy/memset road. static if (!__traits(isZeroInit, T)) { - auto p = typeid(T).initializer(); for ( ; !range.empty ; range.popFront() ) { - static if (__traits(isStaticArray, T)) - { - // static array initializer only contains initialization - // for one element of the static array. - auto elemp = cast(void *) addressOf(range.front); - auto endp = elemp + T.sizeof; - while (elemp < endp) - { - memcpy(elemp, p.ptr, p.length); - elemp += p.length; - } - } - else - { - memcpy(addressOf(range.front), p.ptr, T.sizeof); - } + import core.internal.lifetime : emplaceInitializer; + emplaceInitializer(range.front); } } else @@ -1456,10 +1438,7 @@ private void moveEmplaceImpl(T)(ref scope T target, ref return scope T source) static if (__traits(isZeroInit, T)) () @trusted { memset(&source, 0, sz); }(); else - { - auto init = typeid(T).initializer(); - () @trusted { memcpy(&source, init.ptr, sz); }(); - } + () @trusted { memcpy(&source, __traits(initSymbol, T).ptr, sz); }(); } } else static if (isStaticArray!T) diff --git a/libphobos/src/std/algorithm/sorting.d b/libphobos/src/std/algorithm/sorting.d index f2877cc..ee68b23 100644 --- a/libphobos/src/std/algorithm/sorting.d +++ b/libphobos/src/std/algorithm/sorting.d @@ -3121,14 +3121,14 @@ if (isRandomAccessRange!R && hasLength!R && hasSwappableElements!R && else static assert(false, "`transform` returns an unsortable qualified type: " ~ TB.stringof); - static trustedMalloc(size_t len) @trusted + static trustedMalloc()(size_t len) @trusted { import core.checkedint : mulu; - import core.stdc.stdlib : malloc; + import core.memory : pureMalloc; bool overflow; const nbytes = mulu(len, T.sizeof, overflow); if (overflow) assert(false, "multiplication overflowed"); - T[] result = (cast(T*) malloc(nbytes))[0 .. len]; + T[] result = (cast(T*) pureMalloc(nbytes))[0 .. len]; static if (hasIndirections!T) { import core.memory : GC; @@ -3145,15 +3145,15 @@ if (isRandomAccessRange!R && hasLength!R && hasSwappableElements!R && { foreach (i; 0 .. length) collectException(destroy(xform1[i])); } - static void trustedFree(T[] p) @trusted + static void trustedFree()(T[] p) @trusted { - import core.stdc.stdlib : free; + import core.memory : pureFree; static if (hasIndirections!T) { import core.memory : GC; GC.removeRange(p.ptr); } - free(p.ptr); + pureFree(p.ptr); } trustedFree(xform1); } @@ -3186,7 +3186,7 @@ if (isRandomAccessRange!R && hasLength!R && hasSwappableElements!R) } /// -@safe unittest +@safe pure unittest { import std.algorithm.iteration : map; import std.numeric : entropy; @@ -3207,7 +3207,7 @@ if (isRandomAccessRange!R && hasLength!R && hasSwappableElements!R) assert(isSorted!("a > b")(map!(entropy)(arr))); } -@safe unittest +@safe pure unittest { import std.algorithm.iteration : map; import std.numeric : entropy; @@ -3228,7 +3228,7 @@ if (isRandomAccessRange!R && hasLength!R && hasSwappableElements!R) assert(isSorted!("a < b")(map!(entropy)(arr))); } -@safe unittest +@safe pure unittest { // binary transform function string[] strings = [ "one", "two", "three" ]; @@ -3237,7 +3237,7 @@ if (isRandomAccessRange!R && hasLength!R && hasSwappableElements!R) } // https://issues.dlang.org/show_bug.cgi?id=4909 -@safe unittest +@safe pure unittest { import std.typecons : Tuple; Tuple!(char)[] chars; @@ -3245,7 +3245,7 @@ if (isRandomAccessRange!R && hasLength!R && hasSwappableElements!R) } // https://issues.dlang.org/show_bug.cgi?id=5924 -@safe unittest +@safe pure unittest { import std.typecons : Tuple; Tuple!(char)[] chars; @@ -3253,7 +3253,7 @@ if (isRandomAccessRange!R && hasLength!R && hasSwappableElements!R) } // https://issues.dlang.org/show_bug.cgi?id=13965 -@safe unittest +@safe pure unittest { import std.typecons : Tuple; Tuple!(char)[] chars; @@ -3261,7 +3261,7 @@ if (isRandomAccessRange!R && hasLength!R && hasSwappableElements!R) } // https://issues.dlang.org/show_bug.cgi?id=13965 -@safe unittest +@safe pure unittest { import std.algorithm.iteration : map; import std.numeric : entropy; diff --git a/libphobos/src/std/concurrency.d b/libphobos/src/std/concurrency.d index a9830af..fb383ae 100644 --- a/libphobos/src/std/concurrency.d +++ b/libphobos/src/std/concurrency.d @@ -2149,14 +2149,16 @@ private if (msg.convertsTo!(Args)) { - static if (is(ReturnType!(t) == bool)) + alias RT = ReturnType!(t); + static if (is(RT == bool)) { return msg.map(op); } else { msg.map(op); - return true; + static if (!is(immutable RT == immutable noreturn)) + return true; } } } @@ -2745,7 +2747,8 @@ auto ref initOnce(alias var)(lazy typeof(var) init, shared Mutex mutex) if (!atomicLoad!(MemoryOrder.raw)(flag)) { var = init; - atomicStore!(MemoryOrder.rel)(flag, true); + static if (!is(immutable typeof(var) == immutable noreturn)) + atomicStore!(MemoryOrder.rel)(flag, true); } } } @@ -2827,3 +2830,26 @@ auto ref initOnce(alias var)(lazy typeof(var) init, Mutex mutex) immutable expected = Aggregate(42, [1, 2, 3, 4, 5]); assert(result1 == expected); } + +// Noreturn support +@system unittest +{ + static noreturn foo(int) { throw new Exception(""); } + + if (false) spawn(&foo, 1); + if (false) spawnLinked(&foo, 1); + + if (false) receive(&foo); + if (false) receiveTimeout(Duration.init, &foo); + + // Wrapped in __traits(compiles) to skip codegen which crashes dmd's backend + static assert(__traits(compiles, receiveOnly!noreturn() )); + static assert(__traits(compiles, send(Tid.init, noreturn.init) )); + static assert(__traits(compiles, prioritySend(Tid.init, noreturn.init) )); + static assert(__traits(compiles, yield(noreturn.init) )); + + static assert(__traits(compiles, { + __gshared noreturn n; + initOnce!n(noreturn.init); + })); +} diff --git a/libphobos/src/std/container/dlist.d b/libphobos/src/std/container/dlist.d index cc3e2e8..32d56ec 100644 --- a/libphobos/src/std/container/dlist.d +++ b/libphobos/src/std/container/dlist.d @@ -196,6 +196,12 @@ struct DList(T) T _payload = T.init; + this (BaseNode _base, T _payload) + { + this._base = _base; + this._payload = _payload; + } + inout(BaseNode)* asBaseNode() inout @trusted { return &_base; diff --git a/libphobos/src/std/container/rbtree.d b/libphobos/src/std/container/rbtree.d index f8e70fc..0b0a0b2 100644 --- a/libphobos/src/std/container/rbtree.d +++ b/libphobos/src/std/container/rbtree.d @@ -887,7 +887,7 @@ if (is(typeof(binaryFun!less(T.init, T.init)))) * Returns: * true if node was added */ - private bool _add(return Elem n) + private bool _add(return scope Elem n) { Node result; static if (!allowDuplicates) diff --git a/libphobos/src/std/datetime/interval.d b/libphobos/src/std/datetime/interval.d index 741088a..ba2a210 100644 --- a/libphobos/src/std/datetime/interval.d +++ b/libphobos/src/std/datetime/interval.d @@ -8349,7 +8349,7 @@ private: } { - SysTime stFunc(scope const SysTime st) { return cast(SysTime) st; } + SysTime stFunc(scope const SysTime st) { return SysTime.init; } auto interval = Interval!SysTime(SysTime(DateTime(2010, 7, 4, 12, 1, 7)), SysTime(DateTime(2012, 1, 7, 14, 0, 0))); auto ir = IntervalRange!(SysTime, Direction.fwd)(interval, &stFunc); @@ -8794,7 +8794,7 @@ private: } { - SysTime stFunc(scope const SysTime st) { return cast(SysTime) st; } + SysTime stFunc(scope const SysTime st) { return SysTime.init; } auto posInfInterval = PosInfInterval!SysTime(SysTime(DateTime(2010, 7, 4, 12, 1, 7))); auto ir = PosInfIntervalRange!SysTime(posInfInterval, &stFunc); } @@ -9076,7 +9076,7 @@ private: } { - SysTime stFunc(scope const SysTime st) { return cast(SysTime)(st); } + SysTime stFunc(scope const SysTime st) { return SysTime.init; } auto negInfInterval = NegInfInterval!SysTime(SysTime(DateTime(2012, 1, 7, 14, 0, 0))); auto ir = NegInfIntervalRange!(SysTime)(negInfInterval, &stFunc); } diff --git a/libphobos/src/std/datetime/systime.d b/libphobos/src/std/datetime/systime.d index 4da1281..9b2a844 100644 --- a/libphobos/src/std/datetime/systime.d +++ b/libphobos/src/std/datetime/systime.d @@ -503,7 +503,7 @@ public: given $(REF DateTime,std,datetime,date) is assumed to be in the given time zone. +/ - this(DateTime dateTime, immutable TimeZone tz = null) @safe nothrow + this(DateTime dateTime, return scope immutable TimeZone tz = null) return scope @safe nothrow { try this(dateTime, Duration.zero, tz); @@ -554,7 +554,7 @@ public: $(REF DateTimeException,std,datetime,date) if `fracSecs` is negative or if it's greater than or equal to one second. +/ - this(DateTime dateTime, Duration fracSecs, immutable TimeZone tz = null) @safe + this(DateTime dateTime, Duration fracSecs, return scope immutable TimeZone tz = null) return scope @safe { enforce(fracSecs >= Duration.zero, new DateTimeException("A SysTime cannot have negative fractional seconds.")); enforce(fracSecs < seconds(1), new DateTimeException("Fractional seconds must be less than one second.")); @@ -611,7 +611,7 @@ public: given $(REF Date,std,datetime,date) is assumed to be in the given time zone. +/ - this(Date date, immutable TimeZone tz = null) @safe nothrow + this(Date date, return scope immutable TimeZone tz = null) return scope @safe nothrow { _timezone = tz is null ? LocalTime() : tz; @@ -664,7 +664,7 @@ public: $(LREF SysTime). If null, $(REF LocalTime,std,datetime,timezone) will be used. +/ - this(long stdTime, immutable TimeZone tz = null) @safe pure nothrow + this(long stdTime, return scope immutable TimeZone tz = null) return scope @safe pure nothrow { _stdTime = stdTime; _timezone = tz is null ? LocalTime() : tz; @@ -693,7 +693,7 @@ public: Returns: The `this` of this `SysTime`. +/ - ref SysTime opAssign()(auto ref const(SysTime) rhs) return @safe pure nothrow scope + ref SysTime opAssign()(auto ref const(SysTime) rhs) return scope @safe pure nothrow { _stdTime = rhs._stdTime; _timezone = rhs._timezone; @@ -710,6 +710,7 @@ public: st = other; assert(st == other); + version (none) // https://issues.dlang.org/show_bug.cgi?id=21175 static void testScope(scope ref SysTime left, const scope SysTime right) @safe { left = right; @@ -2184,7 +2185,7 @@ public: hours - adjust the time to this $(LREF SysTime)'s time zone before returning. +/ - @property immutable(TimeZone) timezone() @safe const pure nothrow scope + @property immutable(TimeZone) timezone() @safe const pure nothrow return scope { return _timezone; } @@ -2238,7 +2239,7 @@ public: /++ Returns whether DST is in effect for this $(LREF SysTime). +/ - @property bool dstInEffect() @safe const nothrow scope + @property bool dstInEffect() @safe const nothrow return scope { return _timezone.dstInEffect(_stdTime); } @@ -2261,7 +2262,7 @@ public: Returns what the offset from UTC is for this $(LREF SysTime). It includes the DST offset in effect at that time (if any). +/ - @property Duration utcOffset() @safe const nothrow scope + @property Duration utcOffset() @safe const nothrow return scope { return _timezone.utcOffsetAt(_stdTime); } @@ -9586,13 +9587,13 @@ private: @property override bool hasDST() @safe const nothrow @nogc { return false; } - override bool dstInEffect(long stdTime) @safe const nothrow @nogc { return false; } + override bool dstInEffect(long stdTime) @safe const scope nothrow @nogc { return false; } - override long utcToTZ(long stdTime) @safe const nothrow @nogc { return 0; } + override long utcToTZ(long stdTime) @safe const scope nothrow @nogc { return 0; } - override long tzToUTC(long adjTime) @safe const nothrow @nogc { return 0; } + override long tzToUTC(long adjTime) @safe const scope nothrow @nogc { return 0; } - override Duration utcOffsetAt(long stdTime) @safe const nothrow @nogc { return Duration.zero; } + override Duration utcOffsetAt(long stdTime) @safe const scope nothrow @nogc { return Duration.zero; } private: @@ -9628,7 +9629,7 @@ private: return _timezoneStorage is null ? InitTimeZone() : _timezoneStorage; } - pragma(inline, true) @property void _timezone(immutable TimeZone tz) @safe pure nothrow @nogc scope + pragma(inline, true) @property void _timezone(return scope immutable TimeZone tz) @safe pure nothrow @nogc scope { _timezoneStorage = tz; } diff --git a/libphobos/src/std/datetime/timezone.d b/libphobos/src/std/datetime/timezone.d index 0527580..a55411b 100644 --- a/libphobos/src/std/datetime/timezone.d +++ b/libphobos/src/std/datetime/timezone.d @@ -100,7 +100,7 @@ public: However, on Windows, it may be the unabbreviated name (e.g. Pacific Standard Time). Regardless, it is not the same as name. +/ - @property string stdName() @safe const nothrow + @property string stdName() @safe const scope nothrow { return _stdName; } @@ -113,7 +113,7 @@ public: However, on Windows, it may be the unabbreviated name (e.g. Pacific Daylight Time). Regardless, it is not the same as name. +/ - @property string dstName() @safe const nothrow + @property string dstName() @safe const scope nothrow { return _dstName; } @@ -137,7 +137,7 @@ public: stdTime = The UTC time that needs to be checked for DST in this time zone. +/ - abstract bool dstInEffect(long stdTime) @safe const nothrow; + abstract bool dstInEffect(long stdTime) @safe const scope nothrow; /++ @@ -148,7 +148,7 @@ public: stdTime = The UTC time that needs to be adjusted to this time zone's time. +/ - abstract long utcToTZ(long stdTime) @safe const nothrow; + abstract long utcToTZ(long stdTime) @safe const scope nothrow; /++ @@ -159,7 +159,7 @@ public: adjTime = The time in this time zone that needs to be adjusted to UTC time. +/ - abstract long tzToUTC(long adjTime) @safe const nothrow; + abstract long tzToUTC(long adjTime) @safe const scope nothrow; /++ @@ -170,7 +170,7 @@ public: stdTime = The UTC time for which to get the offset from UTC for this time zone. +/ - Duration utcOffsetAt(long stdTime) @safe const nothrow + Duration utcOffsetAt(long stdTime) @safe const scope nothrow { return dur!"hnsecs"(utcToTZ(stdTime) - stdTime); } @@ -580,7 +580,7 @@ public: dynamically rather than it being fixed like it would be with most time zones. +/ - @property override string stdName() @trusted const nothrow + @property override string stdName() @trusted const scope nothrow { version (Posix) { @@ -665,7 +665,7 @@ public: dynamically rather than it being fixed like it would be with most time zones. +/ - @property override string dstName() @trusted const nothrow + @property override string dstName() @trusted const scope nothrow { version (Posix) { @@ -809,7 +809,7 @@ public: stdTime = The UTC time that needs to be checked for DST in this time zone. +/ - override bool dstInEffect(long stdTime) @trusted const nothrow + override bool dstInEffect(long stdTime) @trusted const scope nothrow { import core.stdc.time : tm; @@ -863,7 +863,7 @@ public: See_Also: `TimeZone.utcToTZ` +/ - override long utcToTZ(long stdTime) @trusted const nothrow + override long utcToTZ(long stdTime) @trusted const scope nothrow { version (Solaris) return stdTime + convert!("seconds", "hnsecs")(tm_gmtoff(stdTime)); @@ -904,7 +904,7 @@ public: adjTime = The time in this time zone that needs to be adjusted to UTC time. +/ - override long tzToUTC(long adjTime) @trusted const nothrow + override long tzToUTC(long adjTime) @trusted const scope nothrow { version (Posix) { @@ -1159,7 +1159,7 @@ public: /++ Always returns false. +/ - override bool dstInEffect(long stdTime) @safe const nothrow + override bool dstInEffect(long stdTime) @safe const scope nothrow { return false; } @@ -1175,7 +1175,7 @@ public: See_Also: `TimeZone.utcToTZ` +/ - override long utcToTZ(long stdTime) @safe const nothrow + override long utcToTZ(long stdTime) @safe const scope nothrow { return stdTime; } @@ -1208,7 +1208,7 @@ public: adjTime = The time in this time zone that needs to be adjusted to UTC time. +/ - override long tzToUTC(long adjTime) @safe const nothrow + override long tzToUTC(long adjTime) @safe const scope nothrow { return adjTime; } @@ -1238,7 +1238,7 @@ public: stdTime = The UTC time for which to get the offset from UTC for this time zone. +/ - override Duration utcOffsetAt(long stdTime) @safe const nothrow + override Duration utcOffsetAt(long stdTime) @safe const scope nothrow { return dur!"hnsecs"(0); } @@ -1285,7 +1285,7 @@ public: /++ Always returns false. +/ - override bool dstInEffect(long stdTime) @safe const nothrow + override bool dstInEffect(long stdTime) @safe const scope nothrow { return false; } @@ -1299,7 +1299,7 @@ public: stdTime = The UTC time that needs to be adjusted to this time zone's time. +/ - override long utcToTZ(long stdTime) @safe const nothrow + override long utcToTZ(long stdTime) @safe const scope nothrow { return stdTime + _utcOffset.total!"hnsecs"; } @@ -1326,7 +1326,7 @@ public: adjTime = The time in this time zone that needs to be adjusted to UTC time. +/ - override long tzToUTC(long adjTime) @safe const nothrow + override long tzToUTC(long adjTime) @safe const scope nothrow { return adjTime - _utcOffset.total!"hnsecs"; } @@ -1352,7 +1352,7 @@ public: stdTime = The UTC time for which to get the offset from UTC for this time zone. +/ - override Duration utcOffsetAt(long stdTime) @safe const nothrow + override Duration utcOffsetAt(long stdTime) @safe const scope nothrow { return _utcOffset; } @@ -1919,7 +1919,7 @@ public: stdTime = The UTC time that needs to be checked for DST in this time zone. +/ - override bool dstInEffect(long stdTime) @safe const nothrow + override bool dstInEffect(long stdTime) @safe const scope nothrow { assert(!_transitions.empty); @@ -1943,7 +1943,7 @@ public: stdTime = The UTC time that needs to be adjusted to this time zone's time. +/ - override long utcToTZ(long stdTime) @safe const nothrow + override long utcToTZ(long stdTime) @safe const scope nothrow { assert(!_transitions.empty); @@ -1968,7 +1968,7 @@ public: adjTime = The time in this time zone that needs to be adjusted to UTC time. +/ - override long tzToUTC(long adjTime) @safe const nothrow + override long tzToUTC(long adjTime) @safe const scope nothrow { assert(!_transitions.empty, "UTC offset's not available"); @@ -2691,7 +2691,7 @@ private: } - int calculateLeapSeconds(long stdTime) @safe const pure nothrow + int calculateLeapSeconds(long stdTime) @safe const scope pure nothrow { if (_leapSeconds.empty) return 0; @@ -2864,7 +2864,7 @@ version (StdDdoc) current dates but will still return true for `hasDST` because the time zone did at some point have DST. +/ - @property override bool hasDST() @safe const nothrow; + @property override bool hasDST() @safe const scope nothrow; /++ @@ -2876,7 +2876,7 @@ version (StdDdoc) stdTime = The UTC time that needs to be checked for DST in this time zone. +/ - override bool dstInEffect(long stdTime) @safe const nothrow; + override bool dstInEffect(long stdTime) @safe const scope nothrow; /++ @@ -2888,7 +2888,7 @@ version (StdDdoc) stdTime = The UTC time that needs to be adjusted to this time zone's time. +/ - override long utcToTZ(long stdTime) @safe const nothrow; + override long utcToTZ(long stdTime) @safe const scope nothrow; /++ @@ -2900,7 +2900,7 @@ version (StdDdoc) adjTime = The time in this time zone that needs to be adjusted to UTC time. +/ - override long tzToUTC(long adjTime) @safe const nothrow; + override long tzToUTC(long adjTime) @safe const scope nothrow; /++ @@ -2945,9 +2945,9 @@ version (StdDdoc) else alias TIME_ZONE_INFORMATION = void*; - static bool _dstInEffect(const TIME_ZONE_INFORMATION* tzInfo, long stdTime) nothrow; - static long _utcToTZ(const TIME_ZONE_INFORMATION* tzInfo, long stdTime, bool hasDST) nothrow; - static long _tzToUTC(const TIME_ZONE_INFORMATION* tzInfo, long adjTime, bool hasDST) nothrow; + static bool _dstInEffect(const scope TIME_ZONE_INFORMATION* tzInfo, long stdTime) nothrow; + static long _utcToTZ(const scope TIME_ZONE_INFORMATION* tzInfo, long stdTime, bool hasDST) nothrow; + static long _tzToUTC(const scope TIME_ZONE_INFORMATION* tzInfo, long adjTime, bool hasDST) nothrow; this() immutable pure { @@ -2967,25 +2967,25 @@ else version (Windows) public: - @property override bool hasDST() @safe const nothrow + @property override bool hasDST() @safe const scope nothrow { return _tzInfo.DaylightDate.wMonth != 0; } - override bool dstInEffect(long stdTime) @safe const nothrow + override bool dstInEffect(long stdTime) @safe const scope nothrow { return _dstInEffect(&_tzInfo, stdTime); } - override long utcToTZ(long stdTime) @safe const nothrow + override long utcToTZ(long stdTime) @safe const scope nothrow { return _utcToTZ(&_tzInfo, stdTime, hasDST); } - override long tzToUTC(long adjTime) @safe const nothrow + override long tzToUTC(long adjTime) @safe const scope nothrow { return _tzToUTC(&_tzInfo, adjTime, hasDST); } @@ -3071,7 +3071,7 @@ else version (Windows) private: - static bool _dstInEffect(const TIME_ZONE_INFORMATION* tzInfo, long stdTime) @trusted nothrow + static bool _dstInEffect(const scope TIME_ZONE_INFORMATION* tzInfo, long stdTime) @trusted nothrow { try { @@ -3155,7 +3155,7 @@ else version (Windows) } - static long _utcToTZ(const TIME_ZONE_INFORMATION* tzInfo, long stdTime, bool hasDST) @safe nothrow + static long _utcToTZ(const scope TIME_ZONE_INFORMATION* tzInfo, long stdTime, bool hasDST) @safe nothrow { if (hasDST && WindowsTimeZone._dstInEffect(tzInfo, stdTime)) return stdTime - convert!("minutes", "hnsecs")(tzInfo.Bias + tzInfo.DaylightBias); @@ -3164,7 +3164,7 @@ else version (Windows) } - static long _tzToUTC(const TIME_ZONE_INFORMATION* tzInfo, long adjTime, bool hasDST) @trusted nothrow + static long _tzToUTC(const scope TIME_ZONE_INFORMATION* tzInfo, long adjTime, bool hasDST) @trusted nothrow { if (hasDST) { diff --git a/libphobos/src/std/file.d b/libphobos/src/std/file.d index 1bfed64..315e054 100644 --- a/libphobos/src/std/file.d +++ b/libphobos/src/std/file.d @@ -1124,7 +1124,7 @@ version (Windows) private ulong makeUlong(DWORD dwLow, DWORD dwHigh) @safe pure } version (Posix) private extern (C) pragma(mangle, stat.mangleof) -int trustedStat(const(FSChar)* namez, ref stat_t buf) @nogc nothrow @trusted; +int trustedStat(scope const(FSChar)* namez, ref stat_t buf) @nogc nothrow @trusted; /** Get size of file `name` in bytes. @@ -1928,7 +1928,7 @@ if (isConvertibleToString!R) assert(!f.exists); } -private bool existsImpl(const(FSChar)* namez) @trusted nothrow @nogc +private bool existsImpl(scope const(FSChar)* namez) @trusted nothrow @nogc { version (Windows) { @@ -2010,7 +2010,7 @@ if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) && version (Windows) { auto namez = name.tempCString!FSChar(); - static auto trustedGetFileAttributesW(const(FSChar)* namez) @trusted + static auto trustedGetFileAttributesW(scope const(FSChar)* namez) @trusted { return GetFileAttributesW(namez); } @@ -2220,7 +2220,7 @@ if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) && version (Windows) { auto namez = name.tempCString!FSChar(); - static auto trustedSetFileAttributesW(const(FSChar)* namez, uint dwFileAttributes) @trusted + static auto trustedSetFileAttributesW(scope const(FSChar)* namez, uint dwFileAttributes) @trusted { return SetFileAttributesW(namez, dwFileAttributes); } @@ -2233,7 +2233,7 @@ if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) && else version (Posix) { auto namez = name.tempCString!FSChar(); - static auto trustedChmod(const(FSChar)* namez, mode_t mode) @trusted + static auto trustedChmod(scope const(FSChar)* namez, mode_t mode) @trusted { return chmod(namez, mode); } @@ -2868,14 +2868,14 @@ if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) && version (Windows) { - static auto trustedChdir(const(FSChar)* pathz) @trusted + static auto trustedChdir(scope const(FSChar)* pathz) @trusted { return SetCurrentDirectoryW(pathz); } } else version (Posix) { - static auto trustedChdir(const(FSChar)* pathz) @trusted + static auto trustedChdir(scope const(FSChar)* pathz) @trusted { return core.sys.posix.unistd.chdir(pathz) == 0; } @@ -2939,7 +2939,7 @@ if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) && version (Windows) { - static auto trustedCreateDirectoryW(const(FSChar)* pathz) @trusted + static auto trustedCreateDirectoryW(scope const(FSChar)* pathz) @trusted { return CreateDirectoryW(pathz, null); } @@ -2953,7 +2953,7 @@ if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) && { import std.conv : octal; - static auto trustedMkdir(const(FSChar)* pathz, mode_t mode) @trusted + static auto trustedMkdir(scope const(FSChar)* pathz, mode_t mode) @trusted { return core.sys.posix.sys.stat.mkdir(pathz, mode); } @@ -3143,14 +3143,14 @@ if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) && version (Windows) { - static auto trustedRmdir(const(FSChar)* pathz) @trusted + static auto trustedRmdir(scope const(FSChar)* pathz) @trusted { return RemoveDirectoryW(pathz); } } else version (Posix) { - static auto trustedRmdir(const(FSChar)* pathz) @trusted + static auto trustedRmdir(scope const(FSChar)* pathz) @trusted { return core.sys.posix.unistd.rmdir(pathz) == 0; } @@ -3859,17 +3859,17 @@ else version (Windows) return _size; } - @property SysTime timeCreated() const pure nothrow scope + @property SysTime timeCreated() const pure nothrow return scope { return cast(SysTime)_timeCreated; } - @property SysTime timeLastAccessed() const pure nothrow scope + @property SysTime timeLastAccessed() const pure nothrow return scope { return cast(SysTime)_timeLastAccessed; } - @property SysTime timeLastModified() const pure nothrow scope + @property SysTime timeLastModified() const pure nothrow return scope { return cast(SysTime)_timeLastModified; } diff --git a/libphobos/src/std/internal/cstring.d b/libphobos/src/std/internal/cstring.d index a61ee81..b21f58d 100644 --- a/libphobos/src/std/internal/cstring.d +++ b/libphobos/src/std/internal/cstring.d @@ -227,7 +227,7 @@ private struct TempCStringBuffer(To = char) @disable this(this); alias ptr this; /// implicitly covert to raw pointer - @property inout(To)* buffPtr() inout + @property inout(To)* buffPtr() return inout { return _ptr == useStack ? _buff.ptr : _ptr; } diff --git a/libphobos/src/std/internal/math/biguintcore.d b/libphobos/src/std/internal/math/biguintcore.d index 7944675..6a93e0a 100644 --- a/libphobos/src/std/internal/math/biguintcore.d +++ b/libphobos/src/std/internal/math/biguintcore.d @@ -879,7 +879,7 @@ public: } // return x / y - static BigUint divInt(T)(scope return BigUint x, T y_) pure nothrow @safe + static BigUint divInt(T)(return scope BigUint x, T y_) pure nothrow @safe if ( is(immutable T == immutable uint) ) { uint y = y_; @@ -942,7 +942,7 @@ public: } // return x / y - static BigUint div(scope return BigUint x, scope BigUint y) pure nothrow @safe + static BigUint div(return scope BigUint x, scope BigUint y) pure nothrow @safe { if (y.data.length > x.data.length) return BigUint(ZERO); @@ -954,7 +954,7 @@ public: } // return x % y - static BigUint mod(scope return BigUint x, scope BigUint y) pure nothrow @safe + static BigUint mod(return scope BigUint x, scope BigUint y) pure nothrow @safe { if (y.data.length > x.data.length) return x; if (y.data.length == 1) @@ -1020,7 +1020,7 @@ public: * exponentiation is used. * Memory allocation is minimized: at most one temporary BigUint is used. */ - static BigUint pow(scope return BigUint x, ulong y) pure nothrow @safe + static BigUint pow(return scope BigUint x, ulong y) pure nothrow @safe { // Deal with the degenerate cases first. if (y == 0) return BigUint(ONE); @@ -1259,7 +1259,7 @@ public: } // Remove leading zeros from x, to restore the BigUint invariant -inout(BigDigit) [] removeLeadingZeros(scope return inout(BigDigit) [] x) pure nothrow @safe +inout(BigDigit) [] removeLeadingZeros(return scope inout(BigDigit) [] x) pure nothrow @safe { size_t k = x.length; while (k>1 && x[k - 1]==0) --k; @@ -1916,7 +1916,7 @@ pure @safe unittest // every 8 digits. // buff.length must be data.length*8 if separator is zero, // or data.length*9 if separator is non-zero. It will be completely filled. -char [] biguintToHex(scope return char [] buff, const scope BigDigit [] data, char separator=0, +char [] biguintToHex(return scope char [] buff, const scope BigDigit [] data, char separator=0, LetterCase letterCase = LetterCase.upper) pure nothrow @safe { int x=0; diff --git a/libphobos/src/std/json.d b/libphobos/src/std/json.d index af7aa38..ea22d63 100644 --- a/libphobos/src/std/json.d +++ b/libphobos/src/std/json.d @@ -159,7 +159,7 @@ struct JSONValue return store.str; } /// ditto - @property string str(return string v) pure nothrow @nogc @trusted return // TODO make @safe + @property string str(return scope string v) pure nothrow @nogc @trusted return // TODO make @safe { assign(v); return v; @@ -282,7 +282,7 @@ struct JSONValue return store.object; } /// ditto - @property JSONValue[string] object(return JSONValue[string] v) pure nothrow @nogc @trusted // TODO make @safe + @property JSONValue[string] object(return scope JSONValue[string] v) pure nothrow @nogc @trusted // TODO make @safe { assign(v); return v; @@ -321,14 +321,14 @@ struct JSONValue (*a)[0] = "world"; // segmentation fault --- */ - @property ref inout(JSONValue[]) array() inout pure @system + @property ref inout(JSONValue[]) array() return scope inout pure @system { enforce!JSONException(type == JSONType.array, "JSONValue is not an array"); return store.array; } /// ditto - @property JSONValue[] array(return JSONValue[] v) pure nothrow @nogc @trusted scope // TODO make @safe + @property JSONValue[] array(return scope JSONValue[] v) pure nothrow @nogc @trusted scope // TODO make @safe { assign(v); return v; @@ -635,7 +635,7 @@ struct JSONValue * Hash syntax for json objects. * Throws: `JSONException` if `type` is not `JSONType.object`. */ - ref inout(JSONValue) opIndex(return string k) inout pure @safe + ref inout(JSONValue) opIndex(return scope string k) inout pure @safe { auto o = this.objectNoRef; return *enforce!JSONException(k in o, diff --git a/libphobos/src/std/net/isemail.d b/libphobos/src/std/net/isemail.d index f2a8ff3..12a29fe 100644 --- a/libphobos/src/std/net/isemail.d +++ b/libphobos/src/std/net/isemail.d @@ -1893,7 +1893,7 @@ Note that only the first item of "matchAll" was ever used in practice so we can return `const(Char)[]` instead of `const(Char)[][]` using a zero-length string to indicate no match. +/ -const(Char)[] matchIPSuffix(Char)(return const(Char)[] s) @nogc nothrow pure @safe +const(Char)[] matchIPSuffix(Char)(return scope const(Char)[] s) @nogc nothrow pure @safe { size_t end = s.length; if (end < 7) return null; diff --git a/libphobos/src/std/process.d b/libphobos/src/std/process.d index 98c5b94..958f606 100644 --- a/libphobos/src/std/process.d +++ b/libphobos/src/std/process.d @@ -276,7 +276,7 @@ static: multi-threaded programs. See e.g. $(LINK2 https://www.gnu.org/software/libc/manual/html_node/Environment-Access.html#Environment-Access, glibc). */ - inout(char)[] opIndexAssign(return inout char[] value, scope const(char)[] name) @trusted + inout(char)[] opIndexAssign(return scope inout char[] value, scope const(char)[] name) @trusted { version (Posix) { @@ -4385,6 +4385,7 @@ else version (Posix) void browse(scope const(char)[] url) nothrow @nogc @safe { + const buffer = url.tempCString(); // Retain buffer until end of scope const(char)*[3] args; // Trusted because it's called with a zero-terminated literal @@ -4408,7 +4409,6 @@ else version (Posix) } } - const buffer = url.tempCString(); // Retain buffer until end of scope args[1] = buffer; args[2] = null; diff --git a/libphobos/src/std/random.d b/libphobos/src/std/random.d index a348356..106e51c 100644 --- a/libphobos/src/std/random.d +++ b/libphobos/src/std/random.d @@ -166,12 +166,16 @@ version (D_InlineAsm_X86_64) version = InlineAsm_X86_Any; assert(10.iota.randomSample(3, rnd2).equal([7, 8, 9])); // Cover all elements in an array in random order - version (X86_64) // https://issues.dlang.org/show_bug.cgi?id=15147 - assert(10.iota.randomCover(rnd2).equal([7, 4, 2, 0, 1, 6, 8, 3, 9, 5])); + version (D_LP64) // https://issues.dlang.org/show_bug.cgi?id=15147 + assert(10.iota.randomCover(rnd2).equal([7, 4, 2, 0, 1, 6, 8, 3, 9, 5])); + else + assert(10.iota.randomCover(rnd2).equal([4, 8, 7, 3, 5, 9, 2, 6, 0, 1])); // Shuffle an array - version (X86_64) // https://issues.dlang.org/show_bug.cgi?id=15147 - assert([0, 1, 2, 4, 5].randomShuffle(rnd2).equal([2, 0, 4, 5, 1])); + version (D_LP64) // https://issues.dlang.org/show_bug.cgi?id=15147 + assert([0, 1, 2, 4, 5].randomShuffle(rnd2).equal([2, 0, 4, 5, 1])); + else + assert([0, 1, 2, 4, 5].randomShuffle(rnd2).equal([4, 2, 5, 0, 1])); } version (StdUnittest) diff --git a/libphobos/src/std/stdio.d b/libphobos/src/std/stdio.d index d3097d5..f30ea80 100644 --- a/libphobos/src/std/stdio.d +++ b/libphobos/src/std/stdio.d @@ -4650,7 +4650,7 @@ if ((isInputRange!R1 && isSomeChar!(ElementEncodingType!R1) || isSomeString!R1) auto namez = name.tempCString!FSChar(); auto modez = mode.tempCString!FSChar(); - static _fopenImpl(const(FSChar)* namez, const(FSChar)* modez) @trusted nothrow @nogc + static _fopenImpl(scope const(FSChar)* namez, scope const(FSChar)* modez) @trusted nothrow @nogc { version (Windows) { diff --git a/libphobos/src/std/typecons.d b/libphobos/src/std/typecons.d index db0e3da..6dee863 100644 --- a/libphobos/src/std/typecons.d +++ b/libphobos/src/std/typecons.d @@ -2239,7 +2239,7 @@ if (is(T == class) || is(T == interface) || isAssociativeArray!T) U stripped; } - void opAssign(T another) pure nothrow @nogc + void opAssign(return scope T another) pure nothrow @nogc { // If `T` defines `opCast` we must infer the safety static if (hasMember!(T, "opCast")) @@ -2271,7 +2271,7 @@ if (is(T == class) || is(T == interface) || isAssociativeArray!T) opAssign(initializer); } - @property inout(T) get() @trusted pure nothrow @nogc inout + @property inout(T) get() @trusted pure nothrow @nogc return scope inout { return original; } @@ -2792,6 +2792,15 @@ struct Nullable(T) } } + this (ref return scope inout Nullable!T rhs) inout + { + _isNull = rhs._isNull; + if (!_isNull) + _value.payload = rhs._value.payload; + else + _value = DontCallDestructorT.init; + } + /** * If they are both null, then they are equal. If one is null and the other * is not, then they are not equal. If they are both non-null, then they are @@ -3284,11 +3293,11 @@ auto nullable(T)(T t) static struct S2 //inspired from 9404 { Nullable!int ni; - this(S2 other) + this(ref S2 other) { ni = other.ni; } - void opAssign(S2 other) + void opAssign(ref S2 other) { ni = other.ni; } @@ -9566,3 +9575,21 @@ unittest assert((a ^ true) == Ternary.no); assert((a ^ false) == Ternary.yes); } + +// https://issues.dlang.org/show_bug.cgi?id=22511 +@safe unittest +{ + static struct S + { + int b; + @disable this(this); + this (ref return scope inout S rhs) inout + { + this.b = rhs.b + 1; + } + } + + Nullable!S s1 = S(1); + Nullable!S s2 = s1; + assert(s2.get().b > s1.get().b); +} diff --git a/libphobos/src/std/uni/package.d b/libphobos/src/std/uni/package.d index 45b7207c..a27cbea 100644 --- a/libphobos/src/std/uni/package.d +++ b/libphobos/src/std/uni/package.d @@ -1987,8 +1987,8 @@ pure: { return this[0] == val[0] && this[1] == val[1]; } - @property ref inout(uint) a() inout { return _tuple[0]; } - @property ref inout(uint) b() inout { return _tuple[1]; } + @property ref inout(uint) a() return inout { return _tuple[0]; } + @property ref inout(uint) b() return inout { return _tuple[1]; } } /** diff --git a/libphobos/src/std/utf.d b/libphobos/src/std/utf.d index be60e7a..866ec48 100644 --- a/libphobos/src/std/utf.d +++ b/libphobos/src/std/utf.d @@ -4315,12 +4315,12 @@ if (isSomeChar!C) { enum Empty = uint.max; // range is empty or just constructed - this(return R r) + this(return scope R r) { this.r = r; } - this(return R r, uint buff) + this(return scope R r, uint buff) { this.r = r; this.buff = buff; @@ -4328,7 +4328,7 @@ if (isSomeChar!C) static if (isBidirectionalRange!R) { - this(return R r, uint frontBuff, uint backBuff) + this(return scope R r, uint frontBuff, uint backBuff) { this.r = r; this.buff = frontBuff; @@ -4436,12 +4436,12 @@ if (isSomeChar!C) { static struct Result { - this(return R r) + this(return scope R r) { this.r = r; } - this(return R r, ushort pos, ushort fill, C[4 / C.sizeof] buf) + this(return scope R r, ushort pos, ushort fill, C[4 / C.sizeof] buf) { this.r = r; this.pos = pos; @@ -4451,7 +4451,7 @@ if (isSomeChar!C) static if (isBidirectionalRange!R) { - this(return R r, ushort frontPos, ushort frontFill, + this(return scope R r, ushort frontPos, ushort frontFill, ushort backPos, ushort backFill, C[4 / C.sizeof] buf) { this.r = r; |