Bug 12424 – Cannot do qualifier-overload with mixin template.
Status
RESOLVED
Resolution
INVALID
Severity
normal
Priority
P3
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2014-03-20T04:48:45Z
Last change time
2023-06-29T10:10:53Z
Assigned to
No Owner
Creator
monarchdodra
Comments
Comment #0 by monarchdodra — 2014-03-20T04:48:45Z
I'm trying to use a mixin template to insert const/non-const functions into my struct. They have the same signature, save for the const qualifier.
The mixins work correctly, inserting the functions. However, the compiler complains of conflicts, instead of recognizing a qualified-overload. The mutable one should take precedence over the non-mutable one: That's the standard lookup rules.
//----
mixin template fooMixin(T)
{
void foo() //L.3
{};
}
struct S
{
//insert "void foo()"
mixin fooMixin!int;
//insert "void foo() const"
const mixin fooMixin!int;
}
void main()
{
const(S) sc;
S s;
sc.foo(); //OK
s.foo(); //FAILS L.22
}
//----
main.d(22): Error: main.S.fooMixin!int.foo at main.d(3) conflicts with main.S.fooMixin!int.foo at main.d(3)
//----
I need to use this approach, because inout doesn't actually work for me here, as the return type depends on how "this" is qualified. See:
https://d.puremagic.com/issues/show_bug.cgi?id=12408
Comment #1 by razvan.nitu1305 — 2023-06-29T10:10:53Z
This is not a bug, but specified behavior. The mixins do insert the functions correctly, however, each function has it's own nested scope. Those scopes are actually "imported" in the scope of S, so it's the same as using imports, the functions are not in the same overload set. The standard look rules are applied and the for the mutable version of S, both functions match, that's why you get an ambiguity error (for more info see: https://dlang.org/spec/template-mixin.html#mixin_scope). To workaround this, you just need to put the functions in the same overload set:
```
mixin template fooMixin(T)
{
void foo() //L.3
{};
}
struct S
{
//insert "void foo()"
mixin fooMixin!int t;
//insert "void foo() const"
const mixin fooMixin!int t2;
// create the overload set
alias foo = t.foo;
alias foo = t2.foo;
}
void main()
{
const(S) sc;
S s;
sc.foo(); //OK
s.foo(); //OK
}
```