proposed @noreturn attribute

Timon Gehr via Digitalmars-d digitalmars-d at puremagic.com
Sun Jul 16 06:03:40 PDT 2017


On 14.07.2017 17:39, Guillaume Boucher wrote:
> 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).
> ...

I think it does, but it is a significantly more invasive language change.

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

I'd say a function with return type Bottom can override any function in 
the base class.

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

The problem for this example is that the current implementation of 
isIntegral would return false for Bottom.

> With @pragma(noreturn) that situation would be no problem.
> ...

pragma(noreturn) is indeed the simpler solution, as it does not interact 
with anything else. The fact that template constraints in some cases 
need to be aware of the existence of Bottom in order to work for Bottom 
is clearly a negative property of this solution in the context of D.

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

You can return 'auto' instead of U. Then the return type will be 
inferred either as U or Bottom.



More information about the Digitalmars-d mailing list