Thread overview
Template Mixin Conflicts
Oct 06, 2014
Alice
Oct 06, 2014
Alice
Oct 06, 2014
ketmar
Oct 06, 2014
Alice
Oct 06, 2014
Ali Çehreli
Oct 08, 2014
Alice
October 06, 2014
Hi,


I've created a template mixin which contains a struct definition. The template is meant to be mixed into each module - to provide a little bit of auto generated info in each module - generated at compile time. As soon as I reference the symbols in any context, it starts complaining about conflicts between the two modules.

It doesn't have to be a struct; the conflicts exist whether I define a struct, class, function, or whatever... any symbol.

It is valid to manually define symbols with the same name in different modules, since they each exist in a different scope, so why does a symbol brought in by a mixin conflict?

Even defining the struct as private doesn't help. Any ideas would be most appreciated.


Here's a very simple failing case:


// ModuleA.d
module ModuleA;

import ModuleB;

mixin MixinUsefulStuff;

pragma(msg, "a = ", SomeData.a); // Error: ModuleB.MixinUsefulStuff!().SomeData at ModuleB.d(5) conflicts with ModuleA.MixinUsefulStuff!().SomeData at ModuleB.d(5)


// ModuleB.d
module ModuleB;

mixin template MixinUsefulStuff()
{
	struct SomeData
	{
		enum a = 123;
	}
}

mixin MixinUsefulStuff;
October 06, 2014
And just this second I found this... but it's a few months old and has no follow up.

http://forum.dlang.org/thread/mailman.1054.1398548687.2763.digitalmars-d-bugs@puremagic.com


On Monday, 6 October 2014 at 12:17:01 UTC, Alice wrote:
> Hi,
>
>
> I've created a template mixin which contains a struct definition. The template is meant to be mixed into each module - to provide a little bit of auto generated info in each module - generated at compile time. As soon as I reference the symbols in any context, it starts complaining about conflicts between the two modules.
>
> It doesn't have to be a struct; the conflicts exist whether I define a struct, class, function, or whatever... any symbol.
>
> It is valid to manually define symbols with the same name in different modules, since they each exist in a different scope, so why does a symbol brought in by a mixin conflict?
>
> Even defining the struct as private doesn't help. Any ideas would be most appreciated.
>
>
> Here's a very simple failing case:
>
>
> // ModuleA.d
> module ModuleA;
>
> import ModuleB;
>
> mixin MixinUsefulStuff;
>
> pragma(msg, "a = ", SomeData.a); // Error: ModuleB.MixinUsefulStuff!().SomeData at ModuleB.d(5) conflicts with ModuleA.MixinUsefulStuff!().SomeData at ModuleB.d(5)
>
>
> // ModuleB.d
> module ModuleB;
>
> mixin template MixinUsefulStuff()
> {
> 	struct SomeData
> 	{
> 		enum a = 123;
> 	}
> }
>
> mixin MixinUsefulStuff;

October 06, 2014
On Mon, 06 Oct 2014 12:17:00 +0000
Alice via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com> wrote:

the joy of mixin bugs, yeah! it's a bug in compiler: it instantiates mixin in invalid scope. for now you can use string mixins, they are working fine.

you also can use this to fix scoping:

=== ModuleA.d ===

  module ModuleA;
  static import ModuleB;
  mixin ModuleB.MixinUsefulStuff;
  pragma(msg, "a = ", SomeData.a);

btw, do you mind to fill a bugreport?


October 06, 2014
> btw, do you mind to fill a bugreport?

Okay, will do so once I get home from work. Thanks for the scope tip. Will try that out later too.

October 06, 2014
On 10/06/2014 05:50 AM, ketmar via Digitalmars-d-learn wrote:
> On Mon, 06 Oct 2014 12:17:00 +0000
> Alice via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com> wrote:
>
> the joy of mixin bugs, yeah! it's a bug in compiler: it instantiates
> mixin in invalid scope. for now you can use string mixins, they are
> working fine.
>
> you also can use this to fix scoping:
>
> === ModuleA.d ===
>
>    module ModuleA;
>    static import ModuleB;
>    mixin ModuleB.MixinUsefulStuff;
>    pragma(msg, "a = ", SomeData.a);
>
> btw, do you mind to fill a bugreport?
>

Another workaround is to mixin into a scope and then bring the names out by alias. Doing the following in both files works:

struct MixinUsefulStuffWrapper
{
    mixin MixinUsefulStuff;
}

alias SomeData = MixinUsefulStuffWrapper.SomeData;

Ali

October 08, 2014
Thanks for your help guys. The workarounds will do for now.

The bug is here: https://issues.dlang.org/show_bug.cgi?id=13587