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 "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
prev sibling next sibling parent =?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
prev sibling next sibling parent "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
prev sibling next sibling 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:
--e89a8f5032e2d54c2c04f37a4cbb
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

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

 I need to change this to explicitly capture the return value of the

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

 {
 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

 {
 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 --e89a8f5032e2d54c2c04f37a4cbb Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable <p dir=3D"ltr"><br> 2014/02/28 23:06 Nordl=C3=B6w &lt;<a href=3D"mailto:per.nordlow gmail.com">= per.nordlow gmail.com</a>&gt;:<br> &gt;<br> &gt; I have a solution to Issue 388 at<br> &gt;<br> &gt; <a href=3D"https://github.com/nordlow/dmd/commits/master">https://gith= ub.com/nordlow/dmd/commits/master</a><br> &gt;<br> &gt; that works nicely for my projects.<br> &gt;<br> &gt; This patch however generates a handful of warnings in Phobos unittests= .<br> &gt;<br> &gt; All of these are IMO fixable except for one which I don&#39;t know how= to fix namely the definition of assertCTFEable in exception.d<br> &gt;<br> &gt; I need to change this to explicitly capture the return value of the te= mplate alias argument dg when this is non-void. My try so far was to change= <br> &gt;<br> &gt; version(unittest) package<br> &gt; property void assertCTFEable(alias dg)()<br> &gt; {<br> &gt; =C2=A0 =C2=A0 static assert({ dg(); return true; }());<br> &gt; =C2=A0 =C2=A0 dg();<br> &gt; }<br> &gt;<br> &gt; to<br> &gt;<br> &gt; version(unittest) package<br> &gt; property void assertCTFEable(alias dg)()<br> &gt; {<br> &gt; =C2=A0 =C2=A0 static assert<br> &gt; =C2=A0 =C2=A0 =C2=A0 =C2=A0 ({<br> &gt; =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 static if (is(typeof(db()) = =3D=3D void)) {<br> &gt; =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 dg();<br> &gt; =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 } else {<br> &gt; =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 auto x =3D dg(= );<br> &gt; =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 }<br> &gt; =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return true;<br> &gt; =C2=A0 =C2=A0 =C2=A0 =C2=A0 }());<br> &gt; =C2=A0 =C2=A0 static if (is(typeof(db()) =3D=3D void)) {<br> &gt; =C2=A0 =C2=A0 =C2=A0 =C2=A0 dg();<br> &gt; =C2=A0 =C2=A0 } else {<br> &gt; =C2=A0 =C2=A0 =C2=A0 =C2=A0 auto x =3D dg();<br> &gt; =C2=A0 =C2=A0 }<br> &gt; }<br> &gt;<br> &gt; gives the following error when in Phobos make unittest:<br> &gt;<br> &gt; std/exception.d(1392): Error: variable std.exception.assertCTFEable!(f= unction ()<br> &gt; {<br> &gt; S[] r =3D array(repeat((S __ctmp1582 =3D 0;<br> &gt; =C2=A0, __ctmp1582).this(1), 2LU));<br> &gt; assert(equal(r, [(S __ctmp1591 =3D 0;<br> &gt; =C2=A0, __ctmp1591).this(1), (S __ctmp1592 =3D 0;<br> &gt; =C2=A0, __ctmp1592).this(1)]));<br> &gt; }<br> &gt; ).assertCTFEable.__lambda1.x type void is inferred from initializer (*= function ()<br> &gt; {<br> &gt; S[] r =3D array(repeat((S __ctmp1582 =3D 0;<br> &gt; =C2=A0, __ctmp1582).this(1), 2LU));<br> &gt; assert(equal(r, [(S __ctmp1591 =3D 0;<br> &gt; =C2=A0, __ctmp1591).this(1), (S __ctmp1592 =3D 0;<br> &gt; =C2=A0, __ctmp1592).this(1)]));<br> &gt; }<br> &gt; )(), and variables cannot be of type void<br> &gt; std/exception.d(1392): Error: expression (*function ()<br> &gt; {<br> &gt; S[] r =3D array(repeat((S __ctmp1582 =3D 0;<br> &gt; =C2=A0, __ctmp1582).this(1), 2LU));<br> &gt; assert(equal(r, [(S __ctmp1591 =3D 0;<br> &gt; =C2=A0, __ctmp1591).this(1), (S __ctmp1592 =3D 0;<br> &gt; =C2=A0, __ctmp1592).this(1)]));<br> &gt; }<br> &gt; )() is void and has no value<br> &gt;<br> &gt; How can I in a general way check if dg evaluates to void or not?</p> <p dir=3D"ltr">Maybe:</p> <p dir=3D"ltr">cast(void)dg();</p> <p dir=3D"ltr">Kenji Hara<br> </p> --e89a8f5032e2d54c2c04f37a4cbb--
Feb 28 2014