proposed @noreturn attribute

Guillaume Boucher via Digitalmars-d digitalmars-d at puremagic.com
Fri Jul 14 08:39:01 PDT 2017


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).



More information about the Digitalmars-d mailing list