July 24, 2019
On 24.07.19 04:12, Ethan wrote:
> On Wednesday, 24 July 2019 at 01:10:34 UTC, Ethan wrote:
>> On Wednesday, 24 July 2019 at 01:06:18 UTC, Ethan wrote:
>>>
>>
>> It's 4am and I was planning on having a major feature finished 8 hours ago, but I've been running in to static foreach and mixin bugs all day.
> 
> https://issues.dlang.org/show_bug.cgi?id=20079
> https://issues.dlang.org/show_bug.cgi?id=20080
> ...

This behavior is by design (for the better or worse, but those are not compiler bugs). You'd need to alias the mixin-template-local symbols into the current scope, or use string mixins instead of template mixins.

> ........and when trying to get to sleep, I decided to try forward declarations for the functions I was having issues with in mixins. And finally hit upon what I think are the root problems I've been having.
> 
> Mixin templates have been broken in one way or another since I started using D in 2012. This static foreach bug I've found just seems to highlight to me that the method of defining a separate scope and importing in to the parent after the fact just plain doesn't work.

mixin templates are _designed_ that way, but `static foreach` doesn't work like this. The additional scopes are introduced for the purpose of containing the `static foreach` loop variable symbols, the symbols generated by `static foreach` themselves are _not_ treated like template mixins, they are inserted into the symbol table of the enclosing scope, but they need to be analyzed in the inner scope so the `static foreach` loop variable is visible.

The `static foreach` implementation explicitly skips scopes containing `static foreach` loop variables (the __anonymous in the error messages) when determining parent symbols, so there is something weird going on. I'm trying to look into this, but I don't have that much time and for some reason the compiler doesn't build on my machine right now (linker errors)...

I have no idea what's up with the visibility problems, as I haven't worked on that part of DMD's code, but probably there is a bad interaction between the code that checks for symbol visibility and `static foreach` loop variable scopes.
July 24, 2019
On Wednesday, 24 July 2019 at 03:01:33 UTC, Adam D. Ruppe wrote:
> Those are by design and it is a fairly useful design too. The presence of a name in the outer scope overrides the same name from the mixin. This allows easy selective customizing of a mixin template as you use it.

https://dlang.org/spec/template-mixin.html

3. Unlike a template instantiation, a template mixin's body is evaluated within the scope where the mixin appears, not where the template declaration is defined. It is analogous to cutting and pasting the body of the template into the location of the mixin into a nested scope. It is useful for injecting parameterized ‘boilerplate’ code, as well as for creating templated nested functions, which is not possible with template instantiations.

So which one is it? Is it copy/paste and a replacement for parameterised C macros as sold, or is it something else?

The spec here reeks of following the implementation instead of being clearly thought out.

And it's far from the first time I've made this point.
July 24, 2019
On Wednesday, 24 July 2019 at 03:11:02 UTC, Ethan wrote:
> So which one is it? Is it copy/paste and a replacement for parameterised C macros as sold, or is it something else?

That page never claims it is a replacement for C macros, and it said it is "analogous" to copy/paste, not identical to it, then goes on to describe specific behaviors.

The details of names appear later on: https://dlang.org/spec/template-mixin.html#mixin_scope including the overriding behavior of locals, conflicts with multiple mixins, and more.

So, yes, it is something else.
July 24, 2019
On 24.07.19 05:10, Timon Gehr wrote:
> 
> The `static foreach` implementation explicitly skips scopes containing `static foreach` loop variables (the __anonymous in the error messages) when determining parent symbols, so there is something weird going on. I'm trying to look into this, but I don't have that much time and for some reason the compiler doesn't build on my machine right now (linker errors)...

https://github.com/dlang/dmd/pull/10214
July 24, 2019
On Wednesday, 24 July 2019 at 03:56:44 UTC, Timon Gehr wrote:
> https://github.com/dlang/dmd/pull/10214

Thank you.


July 25, 2019
On 24.07.19 16:21, Ethan wrote:
> On Wednesday, 24 July 2019 at 03:56:44 UTC, Timon Gehr wrote:
>> https://github.com/dlang/dmd/pull/10214
> 
> Thank you.
> 
> 

No problem, sorry for screwing this up in the first place. Does the patch solve all of your `static foreach`-related problems?
July 25, 2019
On Thursday, 25 July 2019 at 00:15:22 UTC, Timon Gehr wrote:
> No problem, sorry for screwing this up in the first place. Does the patch solve all of your `static foreach`-related problems?

I'll let you know when either I can compile DMD again, or the next point release comes out.
July 26, 2019
On Tuesday, 23 July 2019 at 18:36:19 UTC, Ethan wrote:
> They've most definitely improved since DDMD happened, but they still seem predicated on the idea that people aren't going to be doing a lot of metaprogramming and provide almost no context when you're deep down the meta hole.

The compiler on run.dlang.org provides plenty of context:

/dlang/dmd/linux/bin64/../../src/phobos/std/traits.d(482): Error: local scope __anonymous is not a variable
/dlang/dmd/linux/bin64/../../src/phobos/std/traits.d(580): Error: template instance `std.traits.parentOf!(StructOne)` error instantiating
onlineapp.d(16):        instantiated from here: moduleName!(StructOne)
onlineapp.d(16):        while evaluating pragma(msg, moduleName!(StructOne))

It provides instantiation stack and all line numbers where error occurs.
July 26, 2019
On Friday, 26 July 2019 at 10:33:29 UTC, Kagamin wrote:
> The compiler on run.dlang.org provides plenty of context:
>
> /dlang/dmd/linux/bin64/../../src/phobos/std/traits.d(482): Error: local scope __anonymous is not a variable
> /dlang/dmd/linux/bin64/../../src/phobos/std/traits.d(580): Error: template instance `std.traits.parentOf!(StructOne)` error instantiating
> onlineapp.d(16):        instantiated from here: moduleName!(StructOne)
> onlineapp.d(16):        while evaluating pragma(msg, moduleName!(StructOne))
>
> It provides instantiation stack and all line numbers where error occurs.

Simple use cases like my example are not the problem.

There's an error I was getting the other day that doesn't give a line number, just a file.

Another one starts with "COMPILE".

Both of those required unrolling code and tinkering to work out what was wedged in their bonnet.

And of course I have no idea how to reproduce them either because they're deep in mixins in templated functions in templates in mixins.

I do not write normal code in D. But down in my meta rabbit hole is where all of D's real ultimate power is.
July 26, 2019
On Friday, 26 July 2019 at 12:56:07 UTC, Ethan wrote:
> There's an error I was getting the other day that doesn't give
> a line number, just a file.
> 
> Another one starts with "COMPILE".
> 
> Both of those required unrolling code and tinkering to work out what was wedged in their bonnet.
>
> And of course I have no idea how to reproduce them either because they're deep in mixins in templated functions in templates in mixins.
>
> I do not write normal code in D. But down in my meta rabbit hole is where all of D's real ultimate power is.

I would like to voice a very enthusiastic recommendation for Dustmite for reducing programs to tests. Since it just requires a pass/fail test, it's easy to write a shellscript that checks that DMD's output matches a specific pattern, such as "COMPILE:.*".