D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 22879 - super call ignores overload in mixin
Summary: super call ignores overload in mixin
Status: RESOLVED DUPLICATE of issue 18132
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: x86_64 Linux
: P1 normal
Assignee: No Owner
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2022-03-12 10:34 UTC by Tim
Modified: 2022-03-12 13:39 UTC (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Tim 2022-03-12 10:34:54 UTC
import std.stdio;
class A
{
    void f(){ writeln("A.f"); }
}
class B: A
{
    alias f = A.f;
    mixin X!();
}
mixin template X()
{
    override void f(){ writeln("B.f"); super.f(); }
}
class C: B
{
    override void f(){ writeln("C.f"); super.f(); }
}
void main()
{
    (new C).f();
}

The above code prints the following:
C.f
A.f

Instead the following would be expected:
C.f
B.f
A.f

This affects DMD as a library, because ParseTimeTransitiveVisitor uses a mixin with overloads for visit.
Comment 1 Adam D. Ruppe 2022-03-12 12:52:55 UTC
The presence of that alias complicates things. A template mixin work by name and thus doesn't bring in something that's already there. So with the mixin, `f` is already there, meaning the mixin template's one is overridden by that. That `B.f` function is never part of the virtual tree at all, so `super` here isn't wrong.

I expect the alias is there in the real thing because of overloading arguments in the real thing right?

What you actually want to do is to alias BOTH sets together, not just one:

```
class B: A
{
    alias f = A.f;
    alias f = x.f;
    mixin X!() x;
}
```

This combines the overloads of A with the overloads of X, thus allowing the override to take effect.

This should probably be closed as not a bug, since it is working as designed...
Comment 2 Tim 2022-03-12 13:39:11 UTC
(In reply to Adam D. Ruppe from comment #1)
> I expect the alias is there in the real thing because of overloading
> arguments in the real thing right?
Yes, the class ParseTimeTransitiveVisitor overrides some overloads using a template mixins and uses an alias for other overloads: https://github.com/dlang/dmd/blob/cbba5f41a32cfed7f22a213d537f8e2dee0b92f7/src/dmd/transitivevisitor.d#L17-L21

> 
> What you actually want to do is to alias BOTH sets together, not just one:
> 
> ```
> class B: A
> {
>     alias f = A.f;
>     alias f = x.f;
>     mixin X!() x;
> }
> ```
> 
> This combines the overloads of A with the overloads of X, thus allowing the
> override to take effect.
Thanks, this works.

> 
> This should probably be closed as not a bug, since it is working as
> designed...
I have now seen, that the same problem was already fixed with the same workaround for SemanticTimeTransitiveVisitor: https://github.com/dlang/dmd/pull/7635

I will close this as a duplicate of issue 18132, which was referenced in the pull request.
Comment 3 Tim 2022-03-12 13:39:34 UTC

*** This issue has been marked as a duplicate of issue 18132 ***