www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Make shadowing mixin template names an error (5 years old problem)

reply mw <mw gmail.com> writes:
Make shadowing mixin template names an error

https://github.com/dlang/dmd/issues/23060#issuecomment-4374242813

```
$ cat ctor_bug.d

template Singleton(T) {

     private this() {}  // private, so nobody can new T()!

     // Cache instantiation flag in thread-local bool
     // Thread local
     private static bool instantiated_;

     // Thread global
     private __gshared T instance_;

     static T getSingleton()
     {
         if (!instantiated_)
         {
             synchronized(T.classinfo)
             {
                 if (!instance_)
                 {
                     instance_ = new T();
                 }

                 instantiated_ = true;
             }
         }

         return instance_;
     }
}

class A {
   mixin Singleton!A;

   this() {}  // no dup this() error here!

}




$ dmd --version
DMD64 D Compiler v2.112.0
```

This bug breaks the Singleton pattern
May 05
next sibling parent reply mw <mw gmail.com> writes:
This problem is at least 5 years old.

Seriously, can we fix it?
May 05
parent reply Kapendev <alexandroskapretsos gmail.com> writes:
On Tuesday, 5 May 2026 at 21:51:41 UTC, mw wrote:
 This problem is at least 5 years old.

 Seriously, can we fix it?
It's weird and I don't depend on it, but I like that the basic method wins over the mixin method here.
May 05
parent mw <mw gmail.com> writes:
On Wednesday, 6 May 2026 at 02:51:33 UTC, Kapendev wrote:
 On Tuesday, 5 May 2026 at 21:51:41 UTC, mw wrote:
 This problem is at least 5 years old.

 Seriously, can we fix it?
It's weird and I don't depend on it, but I like that the basic method wins over the mixin method here.
All needed is an error message, let the programmer fix it.
May 05
prev sibling parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On Tuesday, 5 May 2026 at 21:47:09 UTC, mw wrote:
 Make shadowing mixin template names an error

 https://github.com/dlang/dmd/issues/23060#issuecomment-4374242813
Dennis is correct. This is how mixin templates are supposed to work, and if we changed that it would be massively disruptive. I would recommend using string mixins for the behavior you want. -Steve
May 09
next sibling parent Nick Treleaven <nick geany.org> writes:
On Saturday, 9 May 2026 at 12:04:45 UTC, Steven Schveighoffer 
wrote:
 On Tuesday, 5 May 2026 at 21:47:09 UTC, mw wrote:
 Make shadowing mixin template names an error

 https://github.com/dlang/dmd/issues/23060#issuecomment-4374242813
Dennis is correct. This is how mixin templates are supposed to work, and if we changed that it would be massively disruptive.
The original issue requests an error for when the mixin only has one symbol whose name is shadowed at the use site: https://github.com/dlang/dmd/issues/19857
May 09
prev sibling parent reply mw <m g.c> writes:
On Saturday, 9 May 2026 at 12:04:45 UTC, Steven Schveighoffer 
wrote:
 On Tuesday, 5 May 2026 at 21:47:09 UTC, mw wrote:
 Make shadowing mixin template names an error

 https://github.com/dlang/dmd/issues/23060#issuecomment-4374242813
Dennis is correct. This is how mixin templates are supposed to work, and if we changed that it would be massively disruptive. I would recommend using string mixins for the behavior you want.
Using string mixin worked. But string mixin and template mixin have different behavior in this case shows the language need to improve. We can do deprecation slowly. And at least for now, the compiler should generate a warning message.
Jun 21
next sibling parent monkyyy <crazymonkyyy gmail.com> writes:
On Sunday, 21 June 2026 at 18:59:24 UTC, mw wrote:

 like 5th place this conversation happened
you'd break things; if you want an automagic singleton and the like 3 template options airnt good enough it should be a keyword templates airnt ` safe classes`, if you want (bad) oo thoeries make it work with the oo part of the language
Jun 21
prev sibling parent monkyyy <crazymonkyyy gmail.com> writes:
On Sunday, 21 June 2026 at 18:59:24 UTC, mw wrote:
 On Saturday, 9 May 2026 at 12:04:45 UTC, Steven Schveighoffer 
 wrote:
 On Tuesday, 5 May 2026 at 21:47:09 UTC, mw wrote:
 Make shadowing mixin template names an error

 https://github.com/dlang/dmd/issues/23060#issuecomment-4374242813
Dennis is correct. This is how mixin templates are supposed to work, and if we changed that it would be massively disruptive. I would recommend using string mixins for the behavior you want.
Using string mixin worked. But string mixin and template mixin have different behavior in this case shows the language need to improve. We can do deprecation slowly. And at least for now, the compiler should generate a warning message.
new attempt, now with classes: ```d import std; template innate(T,alias value,discrim...){ T innate=value; } template innateclassfriendly(T,discrim...){ T innateclassfriendly; static this(){ innateclassfriendly= new T(allowedtoconstruct()); } } mixin template Singleton(T) { disable this(); unittest{ static assert( ! __traits(compiles, new T()),"please let me break, oo needs you to let less code work ;__;"); } alias getSingleton=innate!(T,T.init,"singleton"); } struct A { mixin Singleton!A; //this() {} // uncommenting this breaks int i=5; } unittest{ assert(A.getSingleton.i==5); A.getSingleton.i=3; } unittest{ assert(A.getSingleton.i==3); } mixin template Singleton2() { alias THIS=typeof(this); disable this(); static assert(is(THIS==struct),"classes dont work with innate for some reason"); alias getSingleton=innate!(THIS,THIS.init,"singleton"); } struct B{ mixin Singleton2!(); //this() {} // uncommenting this breaks float f=13.37; } unittest{ assert(B.getSingleton.f.isClose(13.37)); } struct allowedtoconstruct{} mixin template Singleton3(){ alias THIS=typeof(this); alias getSingleton=innateclassfriendly!(THIS,"singleton"); this()(){ static assert(0,"please use .getSingleton, or ()'s"); } this(allowedtoconstruct){} static THIS opCall()=>getSingleton; } class C{ mixin Singleton3!(); string idk; bool handhold=true; } unittest{ //C ohno=new C();//errors out C().handhold.writeln; } ```
Jun 21