On Monday, 10 July 2017 at 04:02:59 UTC, Nicholas Wilson wrote:
1)@noreturn
2)@disable(return)
3)none
w.r.t optimisation assuming both 1 & 3 impact DMD equally [...]
I don't think that's true. A Bottom type does not cover all use
cases of @noreturn/@pragma(noreturn).
Example 1: Polymorphism
class Bird { void fly() { ... } };
class Penguin : Bird { override void fly() @pragma(noreturn) {
assert(0); } };
class EvolvedPenguin : Penguin { override void fly() { ... } };
There's no way to encode that information in a return type.
Example 2: Compile-time polymorphism
Same as above, except during compile time. While it looks ok in
theory (just return Bottom, and everything is alright), it seems
very tricky to get right. Example from checkedint.d:
auto r = hook.hookOpUnary!op(payload);
return Checked!(typeof(r), Hook)(r);
Let's say the hook refuses to perform hookOpUnary, so r is
Bottom. Unfortunately, Checked!(Bottom, Hook)(r) doesn't compile
(because "if (isIntegral!T || is(T == Checked!(U, H), U, H))"
fails). While Bottom may be substituted into all expressions
(which doesn't seem easy anyway), it for sure can't be inserted
as any template argument. As seen before, Checked is not
Bottom-proof. I would think that most templates are not
Bottom-proof and making them Bottom-proof seems quite a bit of
work.
With @pragma(noreturn) that situation would be no problem.
Example 3: Unreachable statements/Implicit noreturn inference
As pointed out by Steven Schveighoffer, the current
unreachability errors should probably be removed in generic code.
If we do that, then generic functions can be @pragma(noreturn) if
certain conditions are met. A compiler can easily figure that
out, but writing it inside static ifs could be almost impossible.
Assume we have a hook to Checked that disallows casts. Current
signature:
U opCast(U, this _)() if (isIntegral!U || isFloatingPoint!U ||
is(U == bool))
The compiler can figure out that all code paths end with an
@pragma(noreturn), so it can add that pragma implicitly to the
signature. However, the compiler can't change the return type
from U to Bottom (otherwise static equality checks with U will
fail).