www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Checking the Return Type of a Template Alias Parameter in

reply =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= <per.nordlow gmail.com> writes:
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?
Feb 28 2014
next sibling parent reply "John Colvin" <john.loughran.colvin gmail.com> writes:
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.
Feb 28 2014
parent reply =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= <per.nordlow gmail.com> writes:
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
Feb 28 2014
parent reply "John Colvin" <john.loughran.colvin gmail.com> writes:
On Friday, 28 February 2014 at 16:13:19 UTC, Nordlöw wrote:
 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
Should be version(unittest) package property void assertCTFEable(alias dg)() { static assert ({ static if (is(ReturnType!dg == void)) { dg(); } else { auto x = dg(); } return true; }()); static if (is(ReturnType!dg == void)) { dg(); } else { auto x = dg(); } }
Feb 28 2014
parent =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= <per.nordlow gmail.com> writes:
Wonderful!

Now can I request a pull for DMD and Phobos for Issue 3882.

:)
Feb 28 2014
prev sibling parent Kenji Hara <k.hara.pg gmail.com> writes:
2014/02/28 23:06 Nordl=C3=B6w <per.nordlow gmail.com>:
 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()) =3D=3D void)) {
                 dg();
             } else {
                 auto x =3D dg();
             }
             return true;
         }());
     static if (is(typeof(db()) =3D=3D void)) {
         dg();
     } else {
         auto x =3D dg();
     }
 }

 gives the following error when in Phobos make unittest:

 std/exception.d(1392): Error: variable
std.exception.assertCTFEable!(function ()
 {
 S[] r =3D array(repeat((S __ctmp1582 =3D 0;
  , __ctmp1582).this(1), 2LU));
 assert(equal(r, [(S __ctmp1591 =3D 0;
  , __ctmp1591).this(1), (S __ctmp1592 =3D 0;
  , __ctmp1592).this(1)]));
 }
 ).assertCTFEable.__lambda1.x type void is inferred from initializer
(*function ()
 {
 S[] r =3D array(repeat((S __ctmp1582 =3D 0;
  , __ctmp1582).this(1), 2LU));
 assert(equal(r, [(S __ctmp1591 =3D 0;
  , __ctmp1591).this(1), (S __ctmp1592 =3D 0;
  , __ctmp1592).this(1)]));
 }
 )(), and variables cannot be of type void
 std/exception.d(1392): Error: expression (*function ()
 {
 S[] r =3D array(repeat((S __ctmp1582 =3D 0;
  , __ctmp1582).this(1), 2LU));
 assert(equal(r, [(S __ctmp1591 =3D 0;
  , __ctmp1591).this(1), (S __ctmp1592 =3D 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?
Maybe: cast(void)dg(); Kenji Hara
Feb 28 2014