]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - libphobos/src/std/exception.d
d: Import dmd b8384668f, druntime e6caaab9, phobos 5ab9ad256 (v2.098.0-beta.1)
[thirdparty/gcc.git] / libphobos / src / std / exception.d
index 56133c9ad893d11f0ddcd88cf83a845906fd10f0..5fcee2ab598a15dc1b4f35145462a0fef79f1353 100644 (file)
@@ -5,6 +5,7 @@
     handling. It also defines functions intended to aid in unit testing.
 
 $(SCRIPT inhibitQuickIndex = 1;)
+$(DIVC quickindex,
 $(BOOKTABLE,
 $(TR $(TH Category) $(TH Functions))
 $(TR $(TD Assumptions) $(TD
@@ -17,7 +18,6 @@ $(TR $(TD Assumptions) $(TD
 $(TR $(TD Enforce) $(TD
         $(LREF doesPointTo)
         $(LREF enforce)
-        $(LREF enforceEx)
         $(LREF errnoEnforce)
 ))
 $(TR $(TD Handlers) $(TD
@@ -32,68 +32,107 @@ $(TR $(TD Other) $(TD
         $(LREF ErrnoException)
         $(LREF RangePrimitive)
 ))
-)
+))
 
-    Synopsis of some of std.exception's functions:
-    --------------------
-    string synopsis()
-    {
-        FILE* f = enforce(fopen("some/file"));
-        // f is not null from here on
-        FILE* g = enforce!WriteException(fopen("some/other/file", "w"));
-        // g is not null from here on
+    Copyright: Copyright Andrei Alexandrescu 2008-, Jonathan M Davis 2011-.
+    License:   $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0)
+    Authors:   $(HTTP erdani.org, Andrei Alexandrescu) and
+               $(HTTP jmdavisprog.com, Jonathan M Davis)
+    Source:    $(PHOBOSSRC std/exception.d)
 
-        Exception e = collectException(write(g, readln(f)));
-        if (e)
-        {
-            ... an exception occurred...
-            ... We have the exception to play around with...
-        }
+ +/
+module std.exception;
 
-        string msg = collectExceptionMsg(write(g, readln(f)));
-        if (msg)
-        {
-            ... an exception occurred...
-            ... We have the message from the exception but not the exception...
-        }
+/// Synopis
+@system unittest
+{
+    import core.stdc.stdlib : malloc, free;
+    import std.algorithm.comparison : equal;
+    import std.algorithm.iteration : map, splitter;
+    import std.algorithm.searching : endsWith;
+    import std.conv : ConvException, to;
+    import std.range : front, retro;
+
+    // use enforce like assert
+    int a = 3;
+    enforce(a > 2, "a needs to be higher than 2.");
+
+    // enforce can throw a custom exception
+    enforce!ConvException(a > 2, "a needs to be higher than 2.");
+
+    // enforce will return it's input
+    enum size = 42;
+    auto memory = enforce(malloc(size), "malloc failed")[0 .. size];
+    scope(exit) free(memory.ptr);
+
+    // collectException can be used to test for exceptions
+    Exception e = collectException("abc".to!int);
+    assert(e.file.endsWith("conv.d"));
+
+    // and just for the exception message
+    string msg = collectExceptionMsg("abc".to!int);
+    assert(msg == "Unexpected 'a' when converting from type string to type int");
+
+    // assertThrown can be used to assert that an exception is thrown
+    assertThrown!ConvException("abc".to!int);
 
-        char[] line;
-        enforce(readln(f, line));
-        return assumeUnique(line);
+    // ifThrown can be used to provide a default value if an exception is thrown
+    assert("x".to!int().ifThrown(0) == 0);
+
+    // handle is a more advanced version of ifThrown for ranges
+    auto r = "12,1337z32,54".splitter(',').map!(a => to!int(a));
+    auto h = r.handle!(ConvException, RangePrimitive.front, (e, r) => 0);
+    assert(h.equal([12, 0, 54]));
+    assertThrown!ConvException(h.retro.equal([54, 0, 12]));
+
+    // basicExceptionCtors avoids the boilerplate when creating custom exceptions
+    static class MeaCulpa : Exception
+    {
+        mixin basicExceptionCtors;
     }
-    --------------------
+    e = collectException((){throw new MeaCulpa("diagnostic message");}());
+    assert(e.msg == "diagnostic message");
+    assert(e.file == __FILE__);
+    assert(e.line == __LINE__ - 3);
 
-    Copyright: Copyright Andrei Alexandrescu 2008-, Jonathan M Davis 2011-.
-    License:   $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0)
-    Authors:   $(HTTP erdani.org, Andrei Alexandrescu) and Jonathan M Davis
-    Source:    $(PHOBOSSRC std/_exception.d)
+    // assumeWontThrow can be used to cast throwing code into `nothrow`
+    void exceptionFreeCode() nothrow
+    {
+        // auto-decoding only throws if an invalid UTF char is given
+        assumeWontThrow("abc".front);
+    }
 
- +/
-module std.exception;
+    // assumeUnique can be used to cast mutable instance to an `immutable` one
+    // use with care
+    char[] str = "  mutable".dup;
+    str[0 .. 2] = "im";
+    immutable res = assumeUnique(str);
+    assert(res == "immutable");
+}
 
 import std.range.primitives;
 import std.traits;
 
 /++
     Asserts that the given expression does $(I not) throw the given type
-    of $(D Throwable). If a $(D Throwable) of the given type is thrown,
+    of `Throwable`. If a `Throwable` of the given type is thrown,
     it is caught and does not escape assertNotThrown. Rather, an
-    $(D AssertError) is thrown. However, any other $(D Throwable)s will escape.
+    `AssertError` is thrown. However, any other `Throwable`s will escape.
 
     Params:
-        T          = The $(D Throwable) to test for.
+        T          = The `Throwable` to test for.
         expression = The expression to test.
         msg        = Optional message to output on test failure.
                      If msg is empty, and the thrown exception has a
                      non-empty msg field, the exception's msg field
                      will be output on test failure.
         file       = The file where the error occurred.
-                     Defaults to $(D __FILE__).
+                     Defaults to `__FILE__`.
         line       = The line where the error occurred.
-                     Defaults to $(D __LINE__).
+                     Defaults to `__LINE__`.
 
     Throws:
-        $(D AssertError) if the given $(D Throwable) is thrown.
+        `AssertError` if the given `Throwable` is thrown.
 
     Returns:
         the result of `expression`.
@@ -226,22 +265,22 @@ auto assertNotThrown(T : Throwable = Exception, E)
 }
 
 /++
-    Asserts that the given expression throws the given type of $(D Throwable).
-    The $(D Throwable) is caught and does not escape assertThrown. However,
-    any other $(D Throwable)s $(I will) escape, and if no $(D Throwable)
-    of the given type is thrown, then an $(D AssertError) is thrown.
+    Asserts that the given expression throws the given type of `Throwable`.
+    The `Throwable` is caught and does not escape assertThrown. However,
+    any other `Throwable`s $(I will) escape, and if no `Throwable`
+    of the given type is thrown, then an `AssertError` is thrown.
 
     Params:
-        T          = The $(D Throwable) to test for.
+        T          = The `Throwable` to test for.
         expression = The expression to test.
         msg        = Optional message to output on test failure.
         file       = The file where the error occurred.
-                     Defaults to $(D __FILE__).
+                     Defaults to `__FILE__`.
         line       = The line where the error occurred.
-                     Defaults to $(D __LINE__).
+                     Defaults to `__LINE__`.
 
     Throws:
-        $(D AssertError) if the given $(D Throwable) is not thrown.
+        `AssertError` if the given `Throwable` is not thrown.
   +/
 void assertThrown(T : Throwable = Exception, E)
                  (lazy E expression,
@@ -355,55 +394,52 @@ void assertThrown(T : Throwable = Exception, E)
 
 /++
     Enforces that the given value is true.
+    If the given value is false, an exception is thrown.
+    The
+    $(UL
+        $(LI `msg` - error message as a `string`)
+        $(LI `dg` - custom delegate that return a string and is only called if an exception occurred)
+        $(LI `ex` - custom exception to be thrown. It is `lazy` and is only created if an exception occurred)
+    )
 
     Params:
         value = The value to test.
-        E = Exception type to throw if the value evalues to false.
+        E = Exception type to throw if the value evaluates to false.
         msg = The error message to put in the exception if it is thrown.
+        dg = The delegate to be called if the value evaluates to false.
+        ex = The exception to throw if the value evaluates to false.
         file = The source file of the caller.
         line = The line number of the caller.
 
-    Returns: $(D value), if `cast(bool) value` is true. Otherwise,
-    $(D new Exception(msg)) is thrown.
+    Returns: `value`, if `cast(bool) value` is true. Otherwise,
+    depending on the chosen overload, `new Exception(msg)`, `dg()` or `ex` is thrown.
 
     Note:
-        $(D enforce) is used to throw exceptions and is therefore intended to
+        `enforce` is used to throw exceptions and is therefore intended to
         aid in error handling. It is $(I not) intended for verifying the logic
-        of your program. That is what $(D assert) is for. Also, do not use
-        $(D enforce) inside of contracts (i.e. inside of $(D in) and $(D out)
-        blocks and $(D invariant)s), because they will be compiled out when
-        compiling with $(I -release). Use $(D assert) in contracts.
-
-    Example:
-    --------------------
-    auto f = enforce(fopen("data.txt"));
-    auto line = readln(f);
-    enforce(line.length, "Expected a non-empty line.");
-    --------------------
+        of your program. That is what `assert` is for. Also, do not use
+        `enforce` inside of contracts (i.e. inside of `in` and `out`
+        blocks and `invariant`s), because contracts are compiled out when
+        compiling with $(I -release).
+
+        If a delegate is passed, the safety and purity of this function are inferred
+        from `Dg`'s safety and purity.
  +/
-T enforce(E : Throwable = Exception, T)(T value, lazy const(char)[] msg = null,
-string file = __FILE__, size_t line = __LINE__)
-if (is(typeof({ if (!value) {} })))
+template enforce(E : Throwable = Exception)
+if (is(typeof(new E("", string.init, size_t.init)) : Throwable) ||
+    is(typeof(new E(string.init, size_t.init)) : Throwable))
 {
-    if (!value) bailOut!E(file, line, msg);
-    return value;
+    ///
+    T enforce(T)(T value, lazy const(char)[] msg = null,
+    string file = __FILE__, size_t line = __LINE__)
+    if (is(typeof({ if (!value) {} })))
+    {
+        if (!value) bailOut!E(file, line, msg);
+        return value;
+    }
 }
 
-/++
-    Enforces that the given value is true.
-
-    Params:
-        value = The value to test.
-        dg = The delegate to be called if the value evaluates to false.
-        file = The source file of the caller.
-        line = The line number of the caller.
-
-    Returns: $(D value), if `cast(bool) value` is true. Otherwise, the given
-    delegate is called.
-
-    The safety and purity of this function are inferred from $(D Dg)'s safety
-    and purity.
- +/
+/// ditto
 T enforce(T, Dg, string file = __FILE__, size_t line = __LINE__)
     (T value, scope Dg dg)
 if (isSomeFunction!Dg && is(typeof( dg() )) &&
@@ -413,23 +449,40 @@ if (isSomeFunction!Dg && is(typeof( dg() )) &&
     return value;
 }
 
-private void bailOut(E : Throwable = Exception)(string file, size_t line, in char[] msg)
+/// ditto
+T enforce(T)(T value, lazy Throwable ex)
 {
-    static if (is(typeof(new E(string.init, string.init, size_t.init))))
-    {
-        throw new E(msg ? msg.idup : "Enforcement failed", file, line);
-    }
-    else static if (is(typeof(new E(string.init, size_t.init))))
-    {
-        throw new E(file, line);
-    }
-    else
-    {
-        static assert(0, "Expected this(string, string, size_t) or this(string, size_t)" ~
-            " constructor for " ~ __traits(identifier, E));
-    }
+    if (!value) throw ex();
+    return value;
+}
+
+///
+@system unittest
+{
+    import core.stdc.stdlib : malloc, free;
+    import std.conv : ConvException, to;
+
+    // use enforce like assert
+    int a = 3;
+    enforce(a > 2, "a needs to be higher than 2.");
+
+    // enforce can throw a custom exception
+    enforce!ConvException(a > 2, "a needs to be higher than 2.");
+
+    // enforce will return it's input
+    enum size = 42;
+    auto memory = enforce(malloc(size), "malloc failed")[0 .. size];
+    scope(exit) free(memory.ptr);
+}
+
+///
+@safe unittest
+{
+    assertNotThrown(enforce(true, new Exception("this should not be thrown")));
+    assertThrown(enforce(false, new Exception("this should be thrown")));
 }
 
+///
 @safe unittest
 {
     assert(enforce(123) == 123);
@@ -447,9 +500,35 @@ private void bailOut(E : Throwable = Exception)(string file, size_t line, in cha
     }
 }
 
+/// Alias your own enforce function
+@safe unittest
+{
+    import std.conv : ConvException;
+    alias convEnforce = enforce!ConvException;
+    assertNotThrown(convEnforce(true));
+    assertThrown!ConvException(convEnforce(false, "blah"));
+}
+
+private noreturn bailOut(E : Throwable = Exception)(string file, size_t line, scope const(char)[] msg)
+{
+    static if (is(typeof(new E(string.init, string.init, size_t.init))))
+    {
+        throw new E(msg ? msg.idup : "Enforcement failed", file, line);
+    }
+    else static if (is(typeof(new E(string.init, size_t.init))))
+    {
+        throw new E(file, line);
+    }
+    else
+    {
+        static assert(0, "Expected this(string, string, size_t) or this(string, size_t)" ~
+            " constructor for " ~ __traits(identifier, E));
+    }
+}
+
+// https://issues.dlang.org/show_bug.cgi?id=10510
 @safe unittest
 {
-    // Issue 10510
     extern(C) void cFoo() { }
     enforce(false, &cFoo);
 }
@@ -457,14 +536,12 @@ private void bailOut(E : Throwable = Exception)(string file, size_t line, in cha
 // purity and safety inference test
 @system unittest
 {
-    import std.meta : AliasSeq;
-
-    foreach (EncloseSafe; AliasSeq!(false, true))
-    foreach (EnclosePure; AliasSeq!(false, true))
+    static foreach (EncloseSafe; [false, true])
+    static foreach (EnclosePure; [false, true])
     {
-        foreach (BodySafe; AliasSeq!(false, true))
-        foreach (BodyPure; AliasSeq!(false, true))
-        {
+        static foreach (BodySafe; [false, true])
+        static foreach (BodyPure; [false, true])
+        {{
             enum code =
                 "delegate void() " ~
                 (EncloseSafe ? "@safe " : "") ~
@@ -485,11 +562,11 @@ private void bailOut(E : Throwable = Exception)(string file, size_t line, in cha
                         "code = ", code);
 
             static assert(__traits(compiles, mixin(code)()) == expect);
-        }
+        }}
     }
 }
 
-// Test for bugzilla 8637
+// Test for https://issues.dlang.org/show_bug.cgi?id=8637
 @system unittest
 {
     struct S
@@ -523,10 +600,9 @@ private void bailOut(E : Throwable = Exception)(string file, size_t line, in cha
     enforce!E2(s);
 }
 
+// https://issues.dlang.org/show_bug.cgi?id=14685
 @safe unittest
 {
-    // Issue 14685
-
     class E : Exception
     {
         this() { super("Not found"); }
@@ -534,35 +610,6 @@ private void bailOut(E : Throwable = Exception)(string file, size_t line, in cha
     static assert(!__traits(compiles, { enforce!E(false); }));
 }
 
-/++
-    Enforces that the given value is true.
-
-    Params:
-        value = The value to test.
-        ex = The exception to throw if the value evaluates to false.
-
-    Returns: $(D value), if `cast(bool) value` is true. Otherwise, $(D ex) is
-    thrown.
-
-    Example:
-    --------------------
-    auto f = enforce(fopen("data.txt"));
-    auto line = readln(f);
-    enforce(line.length, new IOException); // expect a non-empty line
-    --------------------
- +/
-T enforce(T)(T value, lazy Throwable ex)
-{
-    if (!value) throw ex();
-    return value;
-}
-
-@safe unittest
-{
-    assertNotThrown(enforce(true, new Exception("this should not be thrown")));
-    assertThrown(enforce(false, new Exception("this should be thrown")));
-}
-
 /++
     Enforces that the given value is true, throwing an `ErrnoException` if it
     is not.
@@ -571,125 +618,37 @@ T enforce(T)(T value, lazy Throwable ex)
         value = The value to test.
         msg = The message to include in the `ErrnoException` if it is thrown.
 
-    Returns: $(D value), if `cast(bool) value` is true. Otherwise,
+    Returns: `value`, if `cast(bool) value` is true. Otherwise,
     $(D new ErrnoException(msg)) is thrown.  It is assumed that the last
-    operation set $(D errno) to an error code corresponding with the failed
+    operation set `errno` to an error code corresponding with the failed
     condition.
-
-    Example:
-    --------------------
-    auto f = errnoEnforce(fopen("data.txt"));
-    auto line = readln(f);
-    enforce(line.length); // expect a non-empty line
-    --------------------
- +/
-T errnoEnforce(T, string file = __FILE__, size_t line = __LINE__)
-    (T value, lazy string msg = null)
-{
-    if (!value) throw new ErrnoException(msg, file, line);
-    return value;
-}
-
-
-/++
-    If $(D !value) is $(D false), $(D value) is returned. Otherwise,
-    $(D new E(msg, file, line)) is thrown. Or if $(D E) doesn't take a message
-    and can be constructed with $(D new E(file, line)), then
-    $(D new E(file, line)) will be thrown.
-
-    This is legacy name, it is recommended to use $(D enforce!E) instead.
-
-    Example:
-    --------------------
-    auto f = enforceEx!FileMissingException(fopen("data.txt"));
-    auto line = readln(f);
-    enforceEx!DataCorruptionException(line.length);
-    --------------------
  +/
-template enforceEx(E : Throwable)
-if (is(typeof(new E("", __FILE__, __LINE__))))
-{
-    /++ Ditto +/
-    T enforceEx(T)(T value, lazy string msg = "", string file = __FILE__, size_t line = __LINE__)
-    {
-        if (!value) throw new E(msg, file, line);
-        return value;
-    }
-}
-
-/++ Ditto +/
-template enforceEx(E : Throwable)
-if (is(typeof(new E(__FILE__, __LINE__))) && !is(typeof(new E("", __FILE__, __LINE__))))
-{
-    /++ Ditto +/
-    T enforceEx(T)(T value, string file = __FILE__, size_t line = __LINE__)
-    {
-        if (!value) throw new E(file, line);
-        return value;
-    }
-}
+alias errnoEnforce = enforce!ErrnoException;
 
+///
 @system unittest
 {
-    import core.exception : OutOfMemoryError;
-    import std.array : empty;
-    assertNotThrown(enforceEx!Exception(true));
-    assertNotThrown(enforceEx!Exception(true, "blah"));
-    assertNotThrown(enforceEx!OutOfMemoryError(true));
-
-    {
-        auto e = collectException(enforceEx!Exception(false));
-        assert(e !is null);
-        assert(e.msg.empty);
-        assert(e.file == __FILE__);
-        assert(e.line == __LINE__ - 4);
-    }
+    import core.stdc.stdio : fclose, fgets, fopen;
+    import std.file : thisExePath;
+    import std.string : toStringz;
 
-    {
-        auto e = collectException(enforceEx!Exception(false, "hello", "file", 42));
-        assert(e !is null);
-        assert(e.msg == "hello");
-        assert(e.file == "file");
-        assert(e.line == 42);
-    }
-
-    {
-        auto e = collectException!Error(enforceEx!OutOfMemoryError(false));
-        assert(e !is null);
-        assert(e.msg == "Memory allocation failed");
-        assert(e.file == __FILE__);
-        assert(e.line == __LINE__ - 4);
-    }
-
-    {
-        auto e = collectException!Error(enforceEx!OutOfMemoryError(false, "file", 42));
-        assert(e !is null);
-        assert(e.msg == "Memory allocation failed");
-        assert(e.file == "file");
-        assert(e.line == 42);
-    }
-
-    static assert(!is(typeof(enforceEx!int(true))));
+    auto f = fopen(thisExePath.toStringz, "r").errnoEnforce;
+    scope(exit) fclose(f);
+    char[100] buf;
+    auto line = fgets(buf.ptr, buf.length, f);
+    enforce(line !is null); // expect a non-empty line
 }
 
-@safe unittest
-{
-    alias enf = enforceEx!Exception;
-    assertNotThrown(enf(true));
-    assertThrown(enf(false, "blah"));
-}
-
-
 /++
     Catches and returns the exception thrown from the given expression.
-    If no exception is thrown, then null is returned and $(D result) is
+    If no exception is thrown, then null is returned and `result` is
     set to the result of the expression.
 
-    Note that while $(D collectException) $(I can) be used to collect any
-    $(D Throwable) and not just $(D Exception)s, it is generally ill-advised to
-    catch anything that is neither an $(D Exception) nor a type derived from
-    $(D Exception). So, do not use $(D collectException) to collect
-    non-$(D Exception)s unless you're sure that that's what you really want to
+    Note that while `collectException` $(I can) be used to collect any
+    `Throwable` and not just `Exception`s, it is generally ill-advised to
+    catch anything that is neither an `Exception` nor a type derived from
+    `Exception`. So, do not use `collectException` to collect
+    non-`Exception`s unless you're sure that that's what you really want to
     do.
 
     Params:
@@ -723,14 +682,14 @@ T collectException(T = Exception, E)(lazy E expression, ref E result)
 
 /++
     Catches and returns the exception thrown from the given expression.
-    If no exception is thrown, then null is returned. $(D E) can be
-    $(D void).
-
-    Note that while $(D collectException) $(I can) be used to collect any
-    $(D Throwable) and not just $(D Exception)s, it is generally ill-advised to
-    catch anything that is neither an $(D Exception) nor a type derived from
-    $(D Exception). So, do not use $(D collectException) to collect
-    non-$(D Exception)s unless you're sure that that's what you really want to
+    If no exception is thrown, then null is returned. `E` can be
+    `void`.
+
+    Note that while `collectException` $(I can) be used to collect any
+    `Throwable` and not just `Exception`s, it is generally ill-advised to
+    catch anything that is neither an `Exception` nor a type derived from
+    `Exception`. So, do not use `collectException` to collect
+    non-`Exception`s unless you're sure that that's what you really want to
     do.
 
     Params:
@@ -750,25 +709,26 @@ T collectException(T : Throwable = Exception, E)(lazy E expression)
     return null;
 }
 
+///
 @safe unittest
 {
     int foo() { throw new Exception("blah"); }
-    assert(collectException(foo()));
+    assert(collectException(foo()).msg == "blah");
 }
 
 /++
     Catches the exception thrown from the given expression and returns the
     msg property of that exception. If no exception is thrown, then null is
-    returned. $(D E) can be $(D void).
+    returned. `E` can be `void`.
 
     If an exception is thrown but it has an empty message, then
-    $(D emptyExceptionMsg) is returned.
+    `emptyExceptionMsg` is returned.
 
-    Note that while $(D collectExceptionMsg) $(I can) be used to collect any
-    $(D Throwable) and not just $(D Exception)s, it is generally ill-advised to
-    catch anything that is neither an $(D Exception) nor a type derived from
-    $(D Exception). So, do not use $(D collectExceptionMsg) to collect
-    non-$(D Exception)s unless you're sure that that's what you really want to
+    Note that while `collectExceptionMsg` $(I can) be used to collect any
+    `Throwable` and not just `Exception`s, it is generally ill-advised to
+    catch anything that is neither an `Exception` nor a type derived from
+    `Exception`. So, do not use `collectExceptionMsg` to collect
+    non-`Exception`s unless you're sure that that's what you really want to
     do.
 
     Params:
@@ -808,18 +768,18 @@ enum emptyExceptionMsg = "<Empty Exception Message>";
 
 /**
  * Casts a mutable array to an immutable array in an idiomatic
- * manner. Technically, $(D assumeUnique) just inserts a cast,
+ * manner. Technically, `assumeUnique` just inserts a cast,
  * but its name documents assumptions on the part of the
- * caller. $(D assumeUnique(arr)) should only be called when
+ * caller. `assumeUnique(arr)` should only be called when
  * there are no more active mutable aliases to elements of $(D
- * arr). To strengthen this assumption, $(D assumeUnique(arr))
- * also clears $(D arr) before returning. Essentially $(D
+ * arr). To strengthen this assumption, `assumeUnique(arr)`
+ * also clears `arr` before returning. Essentially $(D
  * assumeUnique(arr)) indicates commitment from the caller that there
- * is no more mutable access to any of $(D arr)'s elements
+ * is no more mutable access to any of `arr`'s elements
  * (transitively), and that all future accesses will be done through
- * the immutable array returned by $(D assumeUnique).
+ * the immutable array returned by `assumeUnique`.
  *
- * Typically, $(D assumeUnique) is used to return arrays from
+ * Typically, `assumeUnique` is used to return arrays from
  * functions that have allocated and built them.
  *
  * Params:
@@ -829,6 +789,7 @@ enum emptyExceptionMsg = "<Empty Exception Message>";
  *
  * Example:
  *
+ * $(RUNNABLE_EXAMPLE
  * ----
  * string letters()
  * {
@@ -840,14 +801,16 @@ enum emptyExceptionMsg = "<Empty Exception Message>";
  *   return assumeUnique(result);
  * }
  * ----
+ * )
  *
- * The use in the example above is correct because $(D result)
- * was private to $(D letters) and is inaccessible in writing
+ * The use in the example above is correct because `result`
+ * was private to `letters` and is inaccessible in writing
  * after the function returns. The following example shows an
- * incorrect use of $(D assumeUnique).
+ * incorrect use of `assumeUnique`.
  *
  * Bad:
  *
+ * $(RUNNABLE_EXAMPLE
  * ----
  * private char[] buffer;
  * string letters(char first, char last)
@@ -862,11 +825,13 @@ enum emptyExceptionMsg = "<Empty Exception Message>";
  *   return assumeUnique(sneaky); // BAD
  * }
  * ----
+ * )
  *
  * The example above wreaks havoc on client code because it is
  * modifying arrays that callers considered immutable. To obtain an
- * immutable array from the writable array $(D buffer), replace
+ * immutable array from the writable array `buffer`, replace
  * the last line with:
+ *
  * ----
  * return to!(string)(sneaky); // not that sneaky anymore
  * ----
@@ -878,6 +843,8 @@ enum emptyExceptionMsg = "<Empty Exception Message>";
  * marked as a pure function. The following example does not
  * need to call assumeUnique because the compiler can infer the
  * uniqueness of the array in the pure function:
+ *
+ * $(RUNNABLE_EXAMPLE
  * ----
  * string letters() pure
  * {
@@ -889,16 +856,17 @@ enum emptyExceptionMsg = "<Empty Exception Message>";
  *   return result;
  * }
  * ----
+ * )
  *
  * For more on infering uniqueness see the $(B unique) and
  * $(B lent) keywords in the
- * $(HTTP archjava.fluid.cs.cmu.edu/papers/oopsla02.pdf, ArchJava)
+ * $(HTTP www.cs.cmu.edu/~aldrich/papers/aldrich-dissertation.pdf, ArchJava)
  * language.
  *
- * The downside of using $(D assumeUnique)'s
+ * The downside of using `assumeUnique`'s
  * convention-based usage is that at this time there is no
  * formal checking of the correctness of the assumption;
- * on the upside, the idiomatic use of $(D assumeUnique) is
+ * on the upside, the idiomatic use of `assumeUnique` is
  * simple and rare enough to be tolerable.
  *
  */
@@ -921,34 +889,38 @@ immutable(T[U]) assumeUnique(T, U)(ref T[U] array) pure nothrow
     return result;
 }
 
+///
 @system unittest
 {
-    // @system due to assumeUnique
     int[] arr = new int[1];
-    auto arr1 = assumeUnique(arr);
-    assert(is(typeof(arr1) == immutable(int)[]) && arr == null);
+    auto arr1 = arr.assumeUnique;
+    static assert(is(typeof(arr1) == immutable(int)[]));
+    assert(arr == null);
+    assert(arr1 == [0]);
 }
 
-// @@@BUG@@@
-version (none) @system unittest
+///
+@system unittest
 {
     int[string] arr = ["a":1];
-    auto arr1 = assumeUnique(arr);
-    assert(is(typeof(arr1) == immutable(int[string])) && arr == null);
+    auto arr1 = arr.assumeUnique;
+    static assert(is(typeof(arr1) == immutable(int[string])));
+    assert(arr == null);
+    assert(arr1.keys == ["a"]);
 }
 
 /**
- * Wraps a possibly-throwing expression in a $(D nothrow) wrapper so that it
- * can be called by a $(D nothrow) function.
+ * Wraps a possibly-throwing expression in a `nothrow` wrapper so that it
+ * can be called by a `nothrow` function.
  *
  * This wrapper function documents commitment on the part of the caller that
  * the appropriate steps have been taken to avoid whatever conditions may
- * trigger an exception during the evaluation of $(D expr).  If it turns out
+ * trigger an exception during the evaluation of `expr`.  If it turns out
  * that the expression $(I does) throw at runtime, the wrapper will throw an
- * $(D AssertError).
+ * `AssertError`.
  *
- * (Note that $(D Throwable) objects such as $(D AssertError) that do not
- * subclass $(D Exception) may be thrown even from $(D nothrow) functions,
+ * (Note that `Throwable` objects such as `AssertError` that do not
+ * subclass `Exception` may be thrown even from `nothrow` functions,
  * since they are considered to be serious runtime problems that cannot be
  * recovered from.)
  *
@@ -984,7 +956,7 @@ T assumeWontThrow(T)(lazy T expr,
 ///
 @safe unittest
 {
-    import std.math : sqrt;
+    import std.math.algebraic : sqrt;
 
     // This function may throw.
     int squareRoot(int x)
@@ -1030,37 +1002,41 @@ Params:
     source = The source object
     target = The target object
 
-Returns: $(D true) if $(D source)'s representation embeds a pointer
-that points to $(D target)'s representation or somewhere inside
+Bugs:
+    The function is explicitly annotated `@nogc` because inference could fail,
+    see $(LINK2 https://issues.dlang.org/show_bug.cgi?id=17084, issue 17084).
+
+Returns: `true` if `source`'s representation embeds a pointer
+that points to `target`'s representation or somewhere inside
 it.
 
-If $(D source) is or contains a dynamic array, then, then these functions will check
-if there is overlap between the dynamic array and $(D target)'s representation.
+If `source` is or contains a dynamic array, then, then these functions will check
+if there is overlap between the dynamic array and `target`'s representation.
 
-If $(D source) is a class, then it will be handled as a pointer.
+If `source` is a class, then it will be handled as a pointer.
 
-If $(D target) is a pointer, a dynamic array or a class, then these functions will only
-check if $(D source) points to $(D target), $(I not) what $(D target) references.
+If `target` is a pointer, a dynamic array or a class, then these functions will only
+check if `source` points to `target`, $(I not) what `target` references.
 
-If $(D source) is or contains a union, then there may be either false positives or
+If `source` is or contains a union or `void[n]`, then there may be either false positives or
 false negatives:
 
-$(D doesPointTo) will return $(D true) if it is absolutely certain
-$(D source) points to $(D target). It may produce false negatives, but never
+`doesPointTo` will return `true` if it is absolutely certain
+`source` points to `target`. It may produce false negatives, but never
 false positives. This function should be prefered when trying to validate
 input data.
 
-$(D mayPointTo) will return $(D false) if it is absolutely certain
-$(D source) does not point to $(D target). It may produce false positives, but never
+`mayPointTo` will return `false` if it is absolutely certain
+`source` does not point to `target`. It may produce false positives, but never
 false negatives. This function should be prefered for defensively choosing a
 code path.
 
-Note: Evaluating $(D doesPointTo(x, x)) checks whether $(D x) has
+Note: Evaluating $(D doesPointTo(x, x)) checks whether `x` has
 internal pointers. This should only be done as an assertive test,
 as the language is free to assume objects don't have internal pointers
 (TDPL 7.1.3.5).
 */
-bool doesPointTo(S, T, Tdummy=void)(auto ref const S source, ref const T target) @trusted pure nothrow
+bool doesPointTo(S, T, Tdummy=void)(auto ref const S source, ref const T target) @nogc @trusted pure nothrow
 if (__traits(isRef, source) || isDynamicArray!S ||
     isPointer!S || is(S == class))
 {
@@ -1080,8 +1056,11 @@ if (__traits(isRef, source) || isDynamicArray!S ||
     }
     else static if (isStaticArray!S)
     {
-        foreach (size_t i; 0 .. S.length)
-            if (doesPointTo(source[i], target)) return true;
+        static if (!is(S == void[n], size_t n))
+        {
+            foreach (ref s; source)
+                if (doesPointTo(s, target)) return true;
+        }
         return false;
     }
     else static if (isDynamicArray!S)
@@ -1122,8 +1101,38 @@ if (__traits(isRef, source) || isDynamicArray!S ||
     }
     else static if (isStaticArray!S)
     {
-        foreach (size_t i; 0 .. S.length)
-            if (mayPointTo(source[i], target)) return true;
+        static if (is(S == void[n], size_t n))
+        {
+            static if (n >= (void[]).sizeof)
+            {
+                // could contain a slice, which could point at anything.
+                // But a void[N] that is all 0 cannot point anywhere
+                import std.algorithm.searching : any;
+                if (__ctfe || any(cast(ubyte[]) source[]))
+                    return true;
+            }
+            else static if (n >= (void*).sizeof)
+            {
+                // Reinterpreting cast is impossible during ctfe
+                if (__ctfe)
+                    return true;
+
+                // Only check for properly aligned pointers
+                enum al = (void*).alignof - 1;
+                const base = cast(size_t) &source;
+                const alBase = (base + al) & ~al;
+
+                if ((n - (alBase - base)) >= (void*).sizeof &&
+                    mayPointTo(*(cast(void**) alBase), target))
+                    return true;
+            }
+        }
+        else
+        {
+            foreach (size_t i; 0 .. S.length)
+                if (mayPointTo(source[i], target)) return true;
+        }
+
         return false;
     }
     else static if (isDynamicArray!S)
@@ -1179,9 +1188,12 @@ bool mayPointTo(S, T)(auto ref const shared S source, ref const shared T target)
 @system unittest
 {
     int i;
+     // trick the compiler when initializing slice
+     // https://issues.dlang.org/show_bug.cgi?id=18637
+    int* p = &i;
     int[]  slice = [0, 1, 2, 3, 4];
     int[5] arr   = [0, 1, 2, 3, 4];
-    int*[]  slicep = [&i];
+    int*[]  slicep = [p];
     int*[1] arrp   = [&i];
 
     // A slice points to all of its members:
@@ -1241,6 +1253,37 @@ bool mayPointTo(S, T)(auto ref const shared S source, ref const shared T target)
     assert(b.doesPointTo(*aLoc)); // b points to where a is pointing
 }
 
+
+version (StdUnittest)
+{
+    // https://issues.dlang.org/show_bug.cgi?id=17084
+    // the bug doesn't happen if these declarations are in the unittest block
+    // (static or not).
+    private struct Page17084
+    {
+        URL17084 url;
+        int opCmp(P)(P) { return 0; }
+        int opCmp(P)(shared(P)) shared { return 0; }
+    }
+
+    private struct URL17084
+    {
+        int[] queryParams;
+        string toString()() const { return ""; }
+        alias toString this;
+    }
+}
+
+// https://issues.dlang.org/show_bug.cgi?id=17084
+@system unittest
+{
+    import std.algorithm.sorting : sort;
+    Page17084[] s;
+    sort(s);
+    shared(Page17084)[] p;
+    sort(p);
+}
+
 @system unittest
 {
     struct S1 { int a; S1 * b; }
@@ -1337,6 +1380,57 @@ bool mayPointTo(S, T)(auto ref const shared S source, ref const shared T target)
     assert( doesPointTo(ss, a));  //The array contains a struct that points to a
     assert(!doesPointTo(ss, b));  //The array doesn't contains a struct that points to b
     assert(!doesPointTo(ss, ss)); //The array doesn't point itself.
+
+    // https://issues.dlang.org/show_bug.cgi?id=20426
+    align((void*).alignof) void[32] voidArr = void;
+    (cast(void*[]) voidArr[])[] = null; // Ensure no false pointers
+
+    // zeroed void ranges can't point at anything
+    assert(!mayPointTo(voidArr, a));
+    assert(!mayPointTo(voidArr, b));
+
+    *cast(void**) &voidArr[16] = &a; // Pointers should be found
+
+    alias SA = void[size_t.sizeof + 3];
+    SA *smallArr1 = cast(SA*)&voidArr;
+    SA *smallArr2 = cast(SA*)&(voidArr[16]);
+
+    // But it should only consider properly aligned pointers
+    // Write single bytes to avoid issues due to misaligned writes
+    void*[1] tmp = [&b];
+    (cast(ubyte[]) voidArr[3 .. 3 + (void*).sizeof])[] = cast(ubyte[]) tmp[];
+
+
+    assert( mayPointTo(*smallArr2, a));
+    assert(!mayPointTo(*smallArr1, b));
+
+    assert(!doesPointTo(voidArr, a)); // Value might be a false pointer
+    assert(!doesPointTo(voidArr, b));
+
+    SA *smallArr3 = cast(SA *) &voidArr[13]; // Works for weird sizes/alignments
+    assert( mayPointTo(*smallArr3, a));
+    assert(!mayPointTo(*smallArr3, b));
+
+    assert(!doesPointTo(*smallArr3, a));
+    assert(!doesPointTo(*smallArr3, b));
+
+    auto v3 = cast(void[3]*) &voidArr[16]; // Arrays smaller than pointers are ignored
+    assert(!mayPointTo(*v3, a));
+    assert(!mayPointTo(*v3, b));
+
+    assert(!doesPointTo(*v3, a));
+    assert(!doesPointTo(*v3, b));
+
+    assert(mayPointTo(voidArr, a)); // slice-contiaining void[N] might point at anything
+    assert(mayPointTo(voidArr, b));
+
+    static assert(() {
+        void[16] arr1 = void;
+        void[size_t.sizeof] arr2 = void;
+        int var;
+        return mayPointTo(arr1, var) && !doesPointTo(arr1, var) &&
+               mayPointTo(arr2, var) && !doesPointTo(arr2, var);
+    }());
 }
 
 
@@ -1425,7 +1519,7 @@ bool mayPointTo(S, T)(auto ref const shared S source, ref const shared T target)
 }
 
 /+
-Returns true if the field at index $(D i) in ($D T) shares its address with another field.
+Returns true if the field at index `i` in ($D T) shares its address with another field.
 
 Note: This does not merelly check if the field is a member of an union, but also that
 it is not a single child.
@@ -1510,53 +1604,57 @@ package string errnoString(int errno) nothrow @trusted
 }
 
 /*********************
- * Thrown if errors that set $(D errno) occur.
+ * Thrown if errors that set `errno` occur.
  */
 class ErrnoException : Exception
 {
-    final @property uint errno() { return _errno; } /// Operating system error code.
+    /// Operating system error code.
+    final @property uint errno() nothrow pure @nogc @safe { return _errno; }
     private uint _errno;
     /// Constructor which takes an error message. The current global $(REF errno, core,stdc,errno) value is used as error code.
-    this(string msg, string file = null, size_t line = 0) @trusted
+    this(string msg, string file = null, size_t line = 0) @safe
     {
         import core.stdc.errno : errno;
         this(msg, errno, file, line);
     }
     /// Constructor which takes an error message and error code.
-    this(string msg, int errno, string file = null, size_t line = 0) @trusted
+    this(string msg, int errno, string file = null, size_t line = 0) @safe
     {
         _errno = errno;
         super(msg ~ " (" ~ errnoString(errno) ~ ")", file, line);
     }
+}
 
-    @system unittest
-    {
-        import core.stdc.errno : errno, EAGAIN;
+///
+@safe unittest
+{
+    import core.stdc.errno : EAGAIN;
+    auto ex = new ErrnoException("oh no", EAGAIN);
+    assert(ex.errno == EAGAIN);
+}
 
-        auto old = errno;
-        scope(exit) errno = old;
+/// errno is used by default if no explicit error code is provided
+@safe unittest
+{
+    import core.stdc.errno : errno, EAGAIN;
 
-        errno = EAGAIN;
-        auto ex = new ErrnoException("oh no");
-        assert(ex.errno == EAGAIN);
-    }
+    auto old = errno;
+    scope(exit) errno = old;
 
-    @system unittest
-    {
-        import core.stdc.errno : EAGAIN;
-        auto ex = new ErrnoException("oh no", EAGAIN);
-        assert(ex.errno == EAGAIN);
-    }
+    // fake that errno got set by the callee
+    errno = EAGAIN;
+    auto ex = new ErrnoException("oh no");
+    assert(ex.errno == EAGAIN);
 }
 
 /++
     ML-style functional exception handling. Runs the supplied expression and
-    returns its result. If the expression throws a $(D Throwable), runs the
+    returns its result. If the expression throws a `Throwable`, runs the
     supplied error handler instead and return its result. The error handler's
     type must be the same as the expression's type.
 
     Params:
-        E            = The type of $(D Throwable)s to catch. Defaults to $(D Exception)
+        E            = The type of `Throwable`s to catch. Defaults to `Exception`
         T1           = The type of the expression.
         T2           = The return type of the error handler.
         expression   = The expression to run and return its result.
@@ -1565,54 +1663,7 @@ class ErrnoException : Exception
     Returns:
         expression, if it does not throw. Otherwise, returns the result of
         errorHandler.
-
-    Example:
-    --------------------
-    //Revert to a default value upon an error:
-    assert("x".to!int().ifThrown(0) == 0);
-    --------------------
-
-    You can also chain multiple calls to ifThrown, each capturing errors from the
-    entire preceding expression.
-
-    Example:
-    --------------------
-    //Chaining multiple calls to ifThrown to attempt multiple things in a row:
-    string s="true";
-    assert(s.to!int().
-            ifThrown(cast(int) s.to!double()).
-            ifThrown(cast(int) s.to!bool())
-            == 1);
-
-    //Respond differently to different types of errors
-    assert(enforce("x".to!int() < 1).to!string()
-            .ifThrown!ConvException("not a number")
-            .ifThrown!Exception("number too small")
-            == "not a number");
-    --------------------
-
-    The expression and the errorHandler must have a common type they can both
-    be implicitly casted to, and that type will be the type of the compound
-    expression.
-
-    Example:
-    --------------------
-    //null and new Object have a common type(Object).
-    static assert(is(typeof(null.ifThrown(new Object())) == Object));
-    static assert(is(typeof((new Object()).ifThrown(null)) == Object));
-
-    //1 and new Object do not have a common type.
-    static assert(!__traits(compiles, 1.ifThrown(new Object())));
-    static assert(!__traits(compiles, (new Object()).ifThrown(1)));
-    --------------------
-
-    If you need to use the actual thrown exception, you can use a delegate.
-    Example:
-    --------------------
-    //Use a lambda to get the thrown object.
-    assert("%s".format().ifThrown!Exception(e => e.classinfo.name) == "std.format.FormatException");
-    --------------------
-    +/
++/
 //lazy version
 CommonType!(T1, T2) ifThrown(E : Throwable = Exception, T1, T2)(lazy scope T1 expression, lazy scope T2 errorHandler)
 {
@@ -1675,6 +1726,59 @@ CommonType!(T1, T2) ifThrown(T1, T2)(lazy scope T1 expression, scope T2 delegate
     }
 }
 
+/// Revert to a default value upon an error:
+@safe unittest
+{
+    import std.conv : to;
+    assert("x".to!int.ifThrown(0) == 0);
+}
+
+/**
+Chain multiple calls to ifThrown, each capturing errors from the
+entire preceding expression.
+*/
+@safe unittest
+{
+    import std.conv : ConvException, to;
+    string s = "true";
+    assert(s.to!int.ifThrown(cast(int) s.to!double)
+                   .ifThrown(cast(int) s.to!bool) == 1);
+
+    s = "2.0";
+    assert(s.to!int.ifThrown(cast(int) s.to!double)
+                   .ifThrown(cast(int) s.to!bool) == 2);
+
+    // Respond differently to different types of errors
+    alias orFallback = (lazy a)  => a.ifThrown!ConvException("not a number")
+                                     .ifThrown!Exception("number too small");
+
+    assert(orFallback(enforce("x".to!int < 1).to!string) == "not a number");
+    assert(orFallback(enforce("2".to!int < 1).to!string) == "number too small");
+}
+
+/**
+The expression and the errorHandler must have a common type they can both
+be implicitly casted to, and that type will be the type of the compound
+expression.
+*/
+@safe unittest
+{
+    // null and new Object have a common type(Object).
+    static assert(is(typeof(null.ifThrown(new Object())) == Object));
+    static assert(is(typeof((new Object()).ifThrown(null)) == Object));
+
+    // 1 and new Object do not have a common type.
+    static assert(!__traits(compiles, 1.ifThrown(new Object())));
+    static assert(!__traits(compiles, (new Object()).ifThrown(1)));
+}
+
+/// Use a lambda to get the thrown object.
+@system unittest
+{
+    import std.format : format;
+    assert("%s".format.ifThrown!Exception(e => e.classinfo.name) == "std.format.FormatException");
+}
+
 //Verify Examples
 @system unittest
 {
@@ -1745,22 +1849,22 @@ CommonType!(T1, T2) ifThrown(T1, T2)(lazy scope T1 expression, scope T2 delegate
     static assert(!__traits(compiles, (new Object()).ifThrown(e=>1)));
 }
 
-version (unittest) package
-@property void assertCTFEable(alias dg)()
+version (StdUnittest) package
+void assertCTFEable(alias dg)()
 {
     static assert({ cast(void) dg(); return true; }());
     cast(void) dg();
 }
 
-/** This $(D enum) is used to select the primitives of the range to handle by the
-  $(LREF handle) range wrapper. The values of the $(D enum) can be $(D OR)'d to
+/** This `enum` is used to select the primitives of the range to handle by the
+  $(LREF handle) range wrapper. The values of the `enum` can be `OR`'d to
   select multiple primitives to be handled.
 
-  $(D RangePrimitive.access) is a shortcut for the access primitives; $(D front),
-  $(D back) and $(D opIndex).
+  `RangePrimitive.access` is a shortcut for the access primitives; `front`,
+  `back` and `opIndex`.
 
-  $(D RangePrimitive.pop) is a shortcut for the mutating primitives;
-  $(D popFront) and $(D popBack).
+  `RangePrimitive.pop` is a shortcut for the mutating primitives;
+  `popFront` and `popBack`.
  */
 enum RangePrimitive
 {
@@ -1778,31 +1882,65 @@ enum RangePrimitive
     pop      = popFront | popBack, /// Ditto
 }
 
+///
+pure @safe unittest
+{
+    import std.algorithm.comparison : equal;
+    import std.algorithm.iteration : map, splitter;
+    import std.conv : to, ConvException;
+
+    auto s = "12,1337z32,54,2,7,9,1z,6,8";
+
+    // The next line composition will throw when iterated
+    // as some elements of the input do not convert to integer
+    auto r = s.splitter(',').map!(a => to!int(a));
+
+    // Substitute 0 for cases of ConvException
+    auto h = r.handle!(ConvException, RangePrimitive.front, (e, r) => 0);
+    assert(h.equal([12, 0, 54, 2, 7, 9, 0, 6, 8]));
+}
+
+///
+pure @safe unittest
+{
+    import std.algorithm.comparison : equal;
+    import std.range : retro;
+    import std.utf : UTFException;
+
+    auto str = "hello\xFFworld"; // 0xFF is an invalid UTF-8 code unit
+
+    auto handled = str.handle!(UTFException, RangePrimitive.access,
+            (e, r) => ' '); // Replace invalid code points with spaces
+
+    assert(handled.equal("hello world")); // `front` is handled,
+    assert(handled.retro.equal("dlrow olleh")); // as well as `back`
+}
+
 /** Handle exceptions thrown from range primitives.
 
 Use the $(LREF RangePrimitive) enum to specify which primitives to _handle.
-Multiple range primitives can be handled at once by using the $(D OR) operator
-or the pseudo-primitives $(D RangePrimitive.access) and $(D RangePrimitive.pop).
+Multiple range primitives can be handled at once by using the `OR` operator
+or the pseudo-primitives `RangePrimitive.access` and `RangePrimitive.pop`.
 All handled primitives must have return types or values compatible with the
 user-supplied handler.
 
 Params:
-    E = The type of $(D Throwable) to _handle.
+    E = The type of `Throwable` to _handle.
     primitivesToHandle = Set of range primitives to _handle.
     handler = The callable that is called when a handled primitive throws a
-    $(D Throwable) of type $(D E). The handler must accept arguments of
+    `Throwable` of type `E`. The handler must accept arguments of
     the form $(D E, ref IRange) and its return value is used as the primitive's
-    return value whenever $(D E) is thrown. For $(D opIndex), the handler can
+    return value whenever `E` is thrown. For `opIndex`, the handler can
     optionally recieve a third argument; the index that caused the exception.
     input = The range to _handle.
 
-Returns: A wrapper $(D struct) that preserves the range interface of $(D input).
+Returns: A wrapper `struct` that preserves the range interface of `input`.
 
 Note:
 Infinite ranges with slicing support must return an instance of
 $(REF Take, std,range) when sliced with a specific lower and upper
-bound (see $(REF hasSlicing, std,range,primitives)); $(D handle) deals with
-this by $(D take)ing 0 from the return value of the handler function and
+bound (see $(REF hasSlicing, std,range,primitives)); `handle` deals with
+this by `take`ing 0 from the return value of the handler function and
 returning that when an exception is caught.
 */
 auto handle(E : Throwable, RangePrimitive primitivesToHandle, alias handler, Range)(Range input)