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