Checking the Return Type of a Template Alias Parameter in assertCTFEable

"Nordlöw" per.nordlow at gmail.com
Fri Feb 28 08:13:17 PST 2014


On Friday, 28 February 2014 at 15:03:29 UTC, John Colvin wrote:
> On Friday, 28 February 2014 at 14:02:35 UTC, Nordlöw wrote:
>> I have a solution to Issue 388 at
>>
>> https://github.com/nordlow/dmd/commits/master
>>
>> that works nicely for my projects.
>>
>> This patch however generates a handful of warnings in Phobos 
>> unittests.
>>
>> All of these are IMO fixable except for one which I don't know 
>> how to fix namely the definition of assertCTFEable in 
>> exception.d
>>
>> I need to change this to explicitly capture the return value 
>> of the template alias argument dg when this is non-void. My 
>> try so far was to change
>>
>> version(unittest) package
>> @property void assertCTFEable(alias dg)()
>> {
>>    static assert({ dg(); return true; }());
>>    dg();
>> }
>>
>> to
>>
>> version(unittest) package
>> @property void assertCTFEable(alias dg)()
>> {
>>    static assert
>>        ({
>>            static if (is(typeof(db()) == void)) {
>>                dg();
>>            } else {
>>                auto x = dg();
>>            }
>>            return true;
>>        }());
>>    static if (is(typeof(db()) == void)) {
>>        dg();
>>    } else {
>>        auto x = dg();
>>    }
>> }
>>
>> gives the following error when in Phobos make unittest:
>>
>> std/exception.d(1392): Error: variable 
>> std.exception.assertCTFEable!(function ()
>> {
>> S[] r = array(repeat((S __ctmp1582 = 0;
>> , __ctmp1582).this(1), 2LU));
>> assert(equal(r, [(S __ctmp1591 = 0;
>> , __ctmp1591).this(1), (S __ctmp1592 = 0;
>> , __ctmp1592).this(1)]));
>> }
>> ).assertCTFEable.__lambda1.x type void is inferred from 
>> initializer (*function ()
>> {
>> S[] r = array(repeat((S __ctmp1582 = 0;
>> , __ctmp1582).this(1), 2LU));
>> assert(equal(r, [(S __ctmp1591 = 0;
>> , __ctmp1591).this(1), (S __ctmp1592 = 0;
>> , __ctmp1592).this(1)]));
>> }
>> )(), and variables cannot be of type void
>> std/exception.d(1392): Error: expression (*function ()
>> {
>> S[] r = array(repeat((S __ctmp1582 = 0;
>> , __ctmp1582).this(1), 2LU));
>> assert(equal(r, [(S __ctmp1591 = 0;
>> , __ctmp1591).this(1), (S __ctmp1592 = 0;
>> , __ctmp1592).this(1)]));
>> }
>> )() is void and has no value
>>
>> How can I in a general way check if dg evaluates to void or 
>> not?
>
> Either use std.traits.ReturnType, or see from it's 
> implementation.

I tried


version(unittest) package
@property void assertCTFEable(alias dg)()
{
     static assert
         ({
             static if (is(ReturnType!(db()) == void)) {
                 dg();
             } else {
                 auto x = dg();
             }
             return true;
         }());
     static if (is(ReturnType!(db()) == void)) {
         dg();
     } else {
         auto x = dg();
     }
}

but this instead fails as

std/exception.d(1392): Error: variable 
std.conv.__unittestL932_18.assertCTFEable!(dg).assertCTFEable.__lambda1.x 
type void is inferred from initializer dg(), and variables cannot 
be of type void
std/exception.d(1392): Error: expression dg() is void and has no 
value
std/exception.d(1402): Error: variable 
std.conv.__unittestL932_18.assertCTFEable!(dg).assertCTFEable.x 
type void is inferred from initializer dg(), and variables cannot 
be of type void
std/exception.d(1402): Error: expression dg() is void and has no 
value
std/conv.d(974): Error: template instance 
std.conv.__unittestL932_18.assertCTFEable!(dg) error instantiating
std/exception.d(1392): Error: variable 
std.exception.assertCTFEable!(function ()
{
assert(to(4611686018427387904LU) == "4611686018427387904");
assert(to(4294967296L) == "4294967296");
assert(to(-138L) == "-138");
}
).assertCTFEable.__lambda1.x type void is inferred from 
initializer (*function ()
{
assert(to(4611686018427387904LU) == "4611686018427387904");
assert(to(4294967296L) == "4294967296");
assert(to(-138L) == "-138");
}
)(), and variables cannot be of type void


More information about the Digitalmars-d mailing list