www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Why this fails when using unittest?

reply Machine Code <jckj33 gmail.com> writes:
outside an unittest, this compiles fine:

	struct A
	{
		enum A foo = "hehe";
		this(string a) { m_a = a; }
		alias m_a this;
		string m_a;
	}

but if you wrap this a unittest {} and compile with
 dmd -unittest -run foo.d
this give the following error:
 cannot implicitly convert expression "hehe" of type string to A
Why does inside a unittest it doesn't work? the constructor this(string) {} seems to get disabled.
Jun 06 2019
next sibling parent Machine Code <jckj33 gmail.com> writes:
On Thursday, 6 June 2019 at 17:40:17 UTC, Machine Code wrote:
 outside an unittest, this compiles fine:

 	struct A
 	{
 		enum A foo = "hehe";
 		this(string a) { m_a = a; }
 		alias m_a this;
 		string m_a;
 	}

 but if you wrap this a unittest {} and compile with
 dmd -unittest -run foo.d
this give the following error:
 cannot implicitly convert expression "hehe" of type string to A
Why does inside a unittest it doesn't work? the constructor this(string) {} seems to get disabled.
I this notice albeit a simple cast workaround that:
 enum A foo = cast(A)"hehe";
or better:
 enum foo = A("hehe");
but isn't that a bug? what am I missing?
Jun 06 2019
prev sibling parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Thursday, 6 June 2019 at 17:40:17 UTC, Machine Code wrote:
 outside an unittest, this compiles fine:

 	struct A
try making it `static struct` instead
 cannot implicitly convert expression "hehe" of type string to A
Why does inside a unittest it doesn't work? the constructor this(string) {} seems to get disabled.
My suspicion is it is trying to access the context of the unittest as a hidden paramater to that constructor there... and in an enum, it can't, just stupid compiler didn't think to mention the hidden arg here. my guess.
Jun 06 2019
next sibling parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 6/6/19 1:49 PM, Adam D. Ruppe wrote:
 On Thursday, 6 June 2019 at 17:40:17 UTC, Machine Code wrote:
 outside an unittest, this compiles fine:

     struct A
try making it `static struct` instead
 cannot implicitly convert expression "hehe" of type string to A
Why does inside a unittest it doesn't work? the constructor this(string) {} seems to get disabled.
My suspicion is it is trying to access the context of the unittest as a hidden paramater to that constructor there... and in an enum, it can't, just stupid compiler didn't think to mention the hidden arg here. my guess.
Yes, correct guess. A unittest block is actually a function, so it's considered an inner struct with a hidden context pointer. -Steve
Jun 06 2019
parent reply Machine Code <jckj33 gmail.com> writes:
On Thursday, 6 June 2019 at 21:02:37 UTC, Steven Schveighoffer 
wrote:
 On 6/6/19 1:49 PM, Adam D. Ruppe wrote:
 On Thursday, 6 June 2019 at 17:40:17 UTC, Machine Code wrote:
 outside an unittest, this compiles fine:

     struct A
try making it `static struct` instead
 cannot implicitly convert expression "hehe" of type string 
 to A
Why does inside a unittest it doesn't work? the constructor this(string) {} seems to get disabled.
My suspicion is it is trying to access the context of the unittest as a hidden paramater to that constructor there... and in an enum, it can't, just stupid compiler didn't think to mention the hidden arg here. my guess.
Yes, correct guess. A unittest block is actually a function, so it's considered an inner struct with a hidden context pointer. -Steve
Intesting, I also tried to declare it inside a function, that did not work either. Is this hidden context pointer a current limitation in CTFE? I've tried to declare the struct at module level and run the functions on static this() to workaround that but to finish, I'd like to eble to run the code in static main() only when unnitest is enabled but so I haven't manged to do that. *Imaginary code* would be: unittest { enum enabled = true; } else { enum enabled = true; } but I was on my mind unittest was similar to static if() but as it's like a function, there are no else let alone acess to enum enabled as true, outside the block but the idea is run (or even only declare) a piece of code (which includes that struct) only if we are an unittest.
Jun 07 2019
parent reply Machine Code <jckj33 gmail.com> writes:
On Friday, 7 June 2019 at 16:30:34 UTC, Machine Code wrote:
 On Thursday, 6 June 2019 at 21:02:37 UTC, Steven Schveighoffer 
 wrote:
 [...]
Intesting, I also tried to declare it inside a function, that did not work either. Is this hidden context pointer a current limitation in CTFE? I've tried to declare the struct at module level and run the functions on static this() to workaround that but to finish, I'd like to eble to run the code in static main() only when unnitest is enabled but so I haven't manged to do that. *Imaginary code* would be: unittest { enum enabled = true; } else { enum enabled = true; } but I was on my mind unittest was similar to static if() but as it's like a function, there are no else let alone acess to enum enabled as true, outside the block but the idea is run (or even only declare) a piece of code (which includes that struct) only if we are an unittest.
All this effort is because I do not want unittest code in a release or even debug. So I want to this be invisible anywhere but unittest or at least simulate that wit static if() how I'm tring to do
Jun 07 2019
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Friday, 7 June 2019 at 16:33:13 UTC, Machine Code wrote:
 All this effort is because I do not want unittest code in a 
 release or even debug.
Well, that part is easy: version(unittest) struct Foo {} at any scope is only build when unittests are turned on in this build.
Jun 07 2019
parent Machine Code <jckj33 gmail.com> writes:
On Friday, 7 June 2019 at 16:41:12 UTC, Adam D. Ruppe wrote:
 On Friday, 7 June 2019 at 16:33:13 UTC, Machine Code wrote:
 All this effort is because I do not want unittest code in a 
 release or even debug.
Well, that part is easy: version(unittest) struct Foo {} at any scope is only build when unittests are turned on in this build.
Thank you! I was about to read version docs to see if I could determine if I was in unittest by versioning. That's exact behavior I was trying to acomplish. I ended up doing this: version(unittest) { struct Foo { } shared static this() { // test code ... } } Act like a unittest {} but I can use CTFE stuff nicely. Thank you all guys.
Jun 07 2019
prev sibling parent Machine Code <jckj33 gmail.com> writes:
On Thursday, 6 June 2019 at 17:49:58 UTC, Adam D. Ruppe wrote:
 On Thursday, 6 June 2019 at 17:40:17 UTC, Machine Code wrote:
 outside an unittest, this compiles fine:

 	struct A
try making it `static struct` instead
didn't work either
 cannot implicitly convert expression "hehe" of type string to 
 A
Why does inside a unittest it doesn't work? the constructor this(string) {} seems to get disabled.
My suspicion is it is trying to access the context of the unittest as a hidden paramater to that constructor there... and in an enum, it can't, just stupid compiler didn't think to mention the hidden arg here. my guess.
So it's a CTFE limitation in unittest/local functions(I also tried to declare that struct inside a function, but did not work either). right? assuming it's an error, it's going to be fixed anytime soon?
Jun 07 2019