Thread overview
mixin template silently `override` without even a warning message!
Oct 09, 2022
mw
Oct 09, 2022
mw
Oct 09, 2022
Mike Parker
Oct 09, 2022
mw
Oct 09, 2022
mw
Oct 09, 2022
mw
Oct 09, 2022
Adam D Ruppe
October 09, 2022

Hi,

I just found another problem:

import std;

template Foo() {
    void foo() {writeln("F");}
    void bar() {foo();}  // fixed to Foo.foo()
}

class A {
    mixin Foo;
    void foo() {writeln("A");}  // I accidentally added this new name-clashed method
}

void main() {
    A a = new A();
    a.bar();  // print F
    a.foo();  // print A
}
  1. class A ends with two methods foo() with the same signature!

  2. whether the foo() in bar() should be fixed to Foo.foo() (non-virtual) is debatable (I can see the reason on both sides).

  3. BUT, the compiler should at least issue a warning message, so the programmer is aware of this name clash. Even when a sub-class override a super-class virtual method, the compiler enforces the user to add override keyword, but why not in this case?

Has this problem be discussed before? and what's the conclusion?

October 09, 2022

Even more fun when we have attribute of the same name:

import std;

template Foo() {
    int a;
    void foo() {writeln(a);}
    void bar() {foo();}
}

class A {
    mixin Foo;
    int a;
    void foo() {writeln(a);}
}

void main() {
    A a = new A();
    a.a = 911;
    a.bar();  // print 0
    a.foo();  // print 911
}

So class A has another hidden Foo.a attribute, but cannot read / write it's value outside of Foo?

October 09, 2022

On Sunday, 9 October 2022 at 07:10:57 UTC, mw wrote:

>

Has this problem be discussed before? and what's the conclusion?

This is documented behavior:

>

The declarations in a mixin are placed in a nested scope and then ‘imported’ into the surrounding scope. If the name of a declaration in a mixin is the same as a declaration in the surrounding scope, the surrounding declaration overrides the mixin one:

And then:

>

If a mixin has an Identifier, it can be used to disambiguate between conflicting symbols:

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

October 09, 2022

On Sunday, 9 October 2022 at 07:24:13 UTC, Mike Parker wrote:

>

On Sunday, 9 October 2022 at 07:10:57 UTC, mw wrote:

>

Has this problem be discussed before? and what's the conclusion?

This is documented behavior:

>

The declarations in a mixin are placed in a nested scope and then ‘imported’ into the surrounding scope. If the name of a declaration in a mixin is the same as a declaration in the surrounding scope, the surrounding declaration overrides the mixin one:

And then:

>

If a mixin has an Identifier, it can be used to disambiguate between conflicting symbols:

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

OK, it's chosen behavior, that's fine.

BUT, as I said, can the compiler issue a warning message?

October 09, 2022

On Sunday, 9 October 2022 at 07:27:54 UTC, mw wrote:

>

On Sunday, 9 October 2022 at 07:24:13 UTC, Mike Parker wrote:

>

On Sunday, 9 October 2022 at 07:10:57 UTC, mw wrote:

>

Has this problem be discussed before? and what's the conclusion?

This is documented behavior:

>

The declarations in a mixin are placed in a nested scope and then ‘imported’ into the surrounding scope. If the name of a declaration in a mixin is the same as a declaration in the surrounding scope, the surrounding declaration overrides the mixin one:

And then:

>

If a mixin has an Identifier, it can be used to disambiguate between conflicting symbols:

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

OK, it's chosen behavior, that's fine.

BUT, as I said, can the compiler issue a warning message?

Especially, this kind of overrides is not the same as the class virtual method override: as I showed in my OP, Foo.bar() is fixed to call Foo.foo(); so we are abuse the concept override here.

Let's call it scope override to differentiate from virtual override, can the compiler at least issue a warning message?

October 09, 2022

On Sunday, 9 October 2022 at 07:27:54 UTC, mw wrote:

>

On Sunday, 9 October 2022 at 07:24:13 UTC, Mike Parker wrote:

>

On Sunday, 9 October 2022 at 07:10:57 UTC, mw wrote:

>

Has this problem be discussed before? and what's the conclusion?

This is documented behavior:

>

The declarations in a mixin are placed in a nested scope and then ‘imported’ into the surrounding scope. If the name of a declaration in a mixin is the same as a declaration in the surrounding scope, the surrounding declaration overrides the mixin one:

And then:

>

If a mixin has an Identifier, it can be used to disambiguate between conflicting symbols:

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

OK, it's chosen behavior, that's fine.

BUT, as I said, can the compiler issue a warning message?

Especially, this kind of overrides is not the same as the class virtual method override: as I showed in my OP, Foo.bar() is fixed to call Foo.foo(), no override happening; so we are abuse the concept override here.

Let's call it scope override to differentiate from virtual override, can the compiler at least issue a warning message?

October 09, 2022

On Sunday, 9 October 2022 at 07:10:57 UTC, mw wrote:

>

template Foo() {
void foo() {writeln("F");}
void bar() {foo();} // fixed to Foo.foo()
}

You can do

void bar() { this.foo(); }

to explicitly call whichever one ended up on the object itself. Otherwise mixin templates work like their own unit with their own namespace.

>
  1. BUT, the compiler should at least issue a warning message, so the programmer is aware of this name clash.

The name "clash" is one of the specific reasons for the mixin template, if it warned there it would be annoying...