Mixin template overloads not working

Steven Schveighoffer schveiguy at gmail.com
Wed Dec 8 00:33:03 UTC 2021


On 12/7/21 1:03 PM, Q. Schroll wrote:
> On Tuesday, 7 December 2021 at 12:43:40 UTC, Rumbu wrote:
>> Bug or feature?
> 
> Feature. It even has a name: "overload set". It keeps you from 
> accidentally calling a function you had no idea existed, for example 
> because of a name clash.

Not in this case. See this demonstration (I removed irrelevant pieces):

```d
class S {}
class A:S {}

class Visitor
{
     void visit(S s) {}
     void visit(A a) {}
}

class Derived : Visitor
{
}

void main()
{
    auto v = new Derived;
    v.visit(A.init); // calls visit(A)
    v.visit(S.init); // calls visit(S)
}
```

Now, let's add a supposed "hiding" function:

```d
class Derived : Visitor
{
    override void visit(A a) {}
}
```

Now, we have these 2 lines:

```d
v.visit(A.init); // works, calls visit(A), just like before
v.visit(S.init); // fails to compile, no overload for S.
```

Where is the hidden function? If you are thinking that just because it's 
not brought forth in the overload set, that's not important. Change the 
two visit parameters to string and int, and it compiles just fine:

```d
class Visitor
{
     void visit(string s) {}
     void visit(int a) {}
}

class Derived : Visitor
{
     override void visit(int a) {} // no problem, even though we don't 
cover the string case
}
```

NOW, if you did instead:

```d
class Derived : Visitor
{
    override void visit(S s) {}
}
```

Now there is a hidden function, because visit(A.init) is going to call 
the derivative visit(S), whereas before it would call Visitor.visit(A).

But that isn't this case.

The spec says:

"It is illegal if, through implicit conversions to the base class, those 
other functions do get called."

The spec does not seem to cover this case, and the rules it states are 
not exactly what the compiler currently implements. I'm not sure where 
the bug is -- spec or implementation -- but there is a disagreement for 
sure.

It's telling that making the S-accepting function final will fix the 
problem.

-Steve


More information about the Digitalmars-d-learn mailing list