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

Reply via email to