www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Compile-time evaluation lost in alias this

reply "Tommi" <tommitissari hotmail.com> writes:
struct ValueImpl
{
     static immutable(int) getValue()
     {
         return 42;
     }
}

struct ValueUser
{
     ValueImpl m_valueImpl;
     alias m_valueImpl this;
}

void main(string[] args)
{
     static assert(ValueImpl.getValue() == 42);
     static assert(ValueUser.getValue() == 42); // (1)
}

(1) Doesn't compile. Error: variable m_valueImpl cannot be read 
at compile time

To use alias this for composition, it would be nice if the 
compile-time evaluable members of the aliased object would remain 
compile-time evaluable even when used through an alias. Is the 
current behavior defined by the language or is it due to the 
compiler (DMD) implementation?
May 30 2012
next sibling parent reply deadalnix <deadalnix gmail.com> writes:
Le 30/05/2012 10:58, Tommi a écrit :
 struct ValueImpl
 {
 static immutable(int) getValue()
 {
 return 42;
 }
 }

 struct ValueUser
 {
 ValueImpl m_valueImpl;
 alias m_valueImpl this;
 }

 void main(string[] args)
 {
 static assert(ValueImpl.getValue() == 42);
 static assert(ValueUser.getValue() == 42); // (1)
 }

 (1) Doesn't compile. Error: variable m_valueImpl cannot be read at
 compile time

 To use alias this for composition, it would be nice if the compile-time
 evaluable members of the aliased object would remain compile-time
 evaluable even when used through an alias. Is the current behavior
 defined by the language or is it due to the compiler (DMD) implementation?

m_valueImpl isn't static and ValueUser not instantiated. I wouldn't expect this to compile at all, CTFE or not.
May 30 2012
parent deadalnix <deadalnix gmail.com> writes:
Le 30/05/2012 14:43, Tommi a écrit :
 ...and that's what I would expect, if the purpose of alias this is to
 bring all the functionality from one type to another. Just like
 inheritance, but not quite.

Except your are not aliasing the type but an instance.
May 30 2012
prev sibling next sibling parent "Tommi" <tommitissari hotmail.com> writes:
Like I said it doesn't compile because it can't do CTFE. But 
remove static in front of the second assert and it compiles (and 
works also during runtime):

assert(ValueUser.getValue() == 42);
May 30 2012
prev sibling next sibling parent "Tommi" <tommitissari hotmail.com> writes:
...and that's what I would expect, if the purpose of alias this 
is to bring all the functionality from one type to another. Just 
like inheritance, but not quite.
May 30 2012
prev sibling next sibling parent kenji hara <k.hara.pg gmail.com> writes:
2012/5/30 Tommi <tommitissari hotmail.com>:
 struct ValueImpl
 {
 =C2=A0 =C2=A0static immutable(int) getValue()
 =C2=A0 =C2=A0{
 =C2=A0 =C2=A0 =C2=A0 =C2=A0return 42;
 =C2=A0 =C2=A0}
 }

 struct ValueUser
 {
 =C2=A0 =C2=A0ValueImpl m_valueImpl;
 =C2=A0 =C2=A0alias m_valueImpl this;
 }

 void main(string[] args)
 {
 =C2=A0 =C2=A0static assert(ValueImpl.getValue() =3D=3D 42);
 =C2=A0 =C2=A0static assert(ValueUser.getValue() =3D=3D 42); // (1)
 }

 (1) Doesn't compile. Error: variable m_valueImpl cannot be read at compil=

 time

 To use alias this for composition, it would be nice if the compile-time
 evaluable members of the aliased object would remain compile-time evaluab=

 even when used through an alias. Is the current behavior defined by the
 language or is it due to the compiler (DMD) implementation?

Looks like a bug. ValueUser.getValue() is translated to ValueUser.m_valueImpl.getValue() with alias this resolution. In here: 1. ValueUser.m_valueImpl is a valid expression. It means just a symbol of variable which declared in ValueUser struct. 2. ValueUser.m_valueImpl is only used for overload resolution of calling getValue() and getValue is static member function, then it is *never* evaluated even in run-time. Please file a report about it in bugzilla. Kenji Hara
May 30 2012
prev sibling next sibling parent "Tommi" <tommitissari hotmail.com> writes:
On Wednesday, 30 May 2012 at 15:04:40 UTC, kenji hara wrote:
 Looks like a bug.

 ValueUser.getValue() is translated to 
 ValueUser.m_valueImpl.getValue()
 with alias this resolution. In here:
 1. ValueUser.m_valueImpl is a valid expression. It means just a 
 symbol
 of variable which declared in ValueUser struct.
 2. ValueUser.m_valueImpl is only used for overload resolution of
 calling getValue() and getValue is static member function, then 
 it is
 *never* evaluated even in run-time.

 Please file a report about it in bugzilla.

 Kenji Hara

Sorry, I'm not sure what you mean. Which one of the following is a bug? 1) The fact that ValueUser.getValue() can't be evaluated at compile time 2) The fact that ValueUser.getValue() compiles and can be evaluated at runtime I'm very new to the language. Just finished reading the book and I'm testing things out.
May 30 2012
prev sibling next sibling parent kenji hara <k.hara.pg gmail.com> writes:
2012/5/31 Tommi <tommitissari hotmail.com>:
 On Wednesday, 30 May 2012 at 15:04:40 UTC, kenji hara wrote:
 Looks like a bug.

 ValueUser.getValue() is translated to ValueUser.m_valueImpl.getValue()
 with alias this resolution. In here:
 1. ValueUser.m_valueImpl is a valid expression. It means just a symbol
 of variable which declared in ValueUser struct.
 2. ValueUser.m_valueImpl is only used for overload resolution of
 calling getValue() and getValue is static member function, then it is
 *never* evaluated even in run-time.

 Please file a report about it in bugzilla.

 Kenji Hara

Sorry, I'm not sure what you mean. Which one of the following is a bug? 1) The fact that ValueUser.getValue() can't be evaluated at compile time 2) The fact that ValueUser.getValue() compiles and can be evaluated at runtime I'm very new to the language. Just finished reading the book and I'm testing things out.

Sorry for my poor English. I'd like to say that ValueUser.getValue() should be evaluated at compile time and runtime. First, we cannot evaluate ValueUser.m_valueImpl in compile time, but can *use* it in compile time. This is a case, using it in typeof expression. static assert(is(typeof(ValueUser.m_valueImpl) == ValueImpl)); Type comparison is compile time operation, then this works. Next, In the expression ValueUser.m_valueImpl.getValue() (equals to ValueUser.getValue()), ValueUser.m_valueImpl is just used to specify where the static function getValue is declared. We can rewrite it like as: typeof(ValueUser.m_valueImpl).getValue() So ValueUser.m_valueImpl is used in compile time, but not evaluated. Therefore original error message is wrong because compiler should not try to evaluate ValueUser.m_valueImpl in compile time. Kenji Hara
May 30 2012
prev sibling next sibling parent "Tommi" <tommitissari hotmail.com> writes:
Thanks for a clear explanation. I filed a bug report:
http://d.puremagic.com/issues/show_bug.cgi?id=8169
May 30 2012
prev sibling next sibling parent kenji hara <k.hara.pg gmail.com> writes:
2012/5/31 Tommi <tommitissari hotmail.com>:
 Thanks for a clear explanation. I filed a bug report:
 http://d.puremagic.com/issues/show_bug.cgi?id=8169

OK. I've posted a pull request for bug 8169. https://github.com/D-Programming-Language/dmd/pull/971 Kenji Hara
May 30 2012
prev sibling parent kenji hara <k.hara.pg gmail.com> writes:
2012/5/31 kenji hara <k.hara.pg gmail.com>:
 2012/5/31 Tommi <tommitissari hotmail.com>:
 Thanks for a clear explanation. I filed a bug report:
 http://d.puremagic.com/issues/show_bug.cgi?id=8169

OK. I've posted a pull request for bug 8169. https://github.com/D-Programming-Language/dmd/pull/971 Kenji Hara

My pull request has been merged into git repository. https://github.com/D-Programming-Language/dmd/commit/bc7144defb372b49f65af67f5c8f9d773d038cbd If no regression by the fix will be found in beta phase, it will be fixed in 2.060 release. Kenji Hara
May 31 2012