Comment #0 by dlang-bugzilla — 2023-05-08T00:29:17Z
//////////// test.d ///////////
template f1(alias fun)
{
struct UnusedButConflicting
{
}
auto f1()
{
}
}
template f2(T)
{
alias fun = {};
auto f2(auto ref T)
{
f1!fun();
}
}
auto f3(T)(T value)
{
f2(value);
}
void main()
{
f2(5);
f3(5);
}
///////////////////////////////
Output:
test.d(3): Error: struct `test.f1!(function ()
{
}
).UnusedButConflicting` already exists at test.d(3). Perhaps in another function with the same name?
test.d(18): Error: template instance `test.f1!(function ()
{
}
)` error instantiating
test.d(24): instantiated from here: `f2!int`
test.d(30): instantiated from here: `f3!int`
-----
I think the "auto ref" is somehow to blame. The type is the same, but the "auto ref" is instantiated to with/without ref, which seems to cause two UnusedButConflicting instances with the same mangling?
Comment #1 by dlang-bugzilla — 2023-05-08T00:31:11Z
BTW, it compiles in 2.080.1. I did not mark it as a regression because, even though the release compiler does not produce any errors, the debug build of that version trips an assertion:
core.exception.AssertError@dmd/dsymbolsem.d(4208): Assertion failure
----------------
dmd() [0x5869ff]
dmd(_ZN22DsymbolSemanticVisitor5visitEP17StructDeclaration+0x8ea) [0x582552]
dmd(_ZN17StructDeclaration6acceptEP7Visitor+0x1d) [0x55d31d]
dmd(_Z15dsymbolSemanticP7DsymbolP5Scope+0x3d) [0x5779d5]
dmd(_ZN16TemplateInstance13expandMembersEP5Scope+0xdd) [0x596735]
dmd(_ZN16TemplateInstance16tryExpandMembersEP5Scope+0x5c) [0x5967a4]
dmd(void dmd.dsymbolsem.templateInstanceSemantic(dmd.dtemplate.TemplateInstance, dmd.dscope.Scope*, dmd.root.array.Array!(dmd.expression.Expression).Array*)+0x8d8) [0x585b50]
dmd(_ZN22DsymbolSemanticVisitor5visitEP16TemplateInstance+0x16) [0x57da96]
dmd(_ZN16TemplateInstance6acceptEP7Visitor+0x1d) [0x596845]
dmd(_Z15dsymbolSemanticP7DsymbolP5Scope+0x3d) [0x5779d5]
dmd(_ZN25ExpressionSemanticVisitor5visitEP8ScopeExp+0x3c6) [0x5af336]
dmd(_ZN8ScopeExp6acceptEP7Visitor+0x1d) [0x5a36fd]
dmd(_Z18expressionSemanticP10ExpressionP5Scope+0x43) [0x5c38fb]
dmd(_ZN25ExpressionSemanticVisitor5visitEP7CallExp+0x49e) [0x5b1cae]
dmd(_ZN7CallExp6acceptEP7Visitor+0x1d) [0x5a6b7d]
dmd(_Z18expressionSemanticP10ExpressionP5Scope+0x43) [0x5c38fb]
dmd(_ZN24StatementSemanticVisitor5visitEP12ExpStatement+0x50) [0x63d278]
dmd(_ZN12ExpStatement6acceptEP7Visitor+0x1d) [0x622d1d]
dmd(_Z17statementSemanticP9StatementP5Scope+0x43) [0x63d19b]
dmd(_ZN24StatementSemanticVisitor5visitEP17CompoundStatement+0xe8) [0x63d518]
dmd(_ZN17CompoundStatement6acceptEP7Visitor+0x1d) [0x62344d]
dmd(_Z17statementSemanticP9StatementP5Scope+0x43) [0x63d19b]
dmd(_ZN16Semantic3Visitor5visitEP15FuncDeclaration+0x1174) [0x6504dc]
dmd(_ZN15FuncDeclaration6acceptEP7Visitor+0x1d) [0x5c9fd5]
dmd(_Z9semantic3P7DsymbolP5Scope+0x3d) [0x64ef7d]
dmd(_ZN16Semantic3Visitor5visitEP16TemplateInstance+0x14f) [0x64f0f7]
dmd(_ZN16TemplateInstance6acceptEP7Visitor+0x1d) [0x596845]
dmd(_Z9semantic3P7DsymbolP5Scope+0x3d) [0x64ef7d]
dmd(_ZN16TemplateInstance12trySemantic3EP5Scope+0x5c) [0x59680c]
dmd(void dmd.dsymbolsem.templateInstanceSemantic(dmd.dtemplate.TemplateInstance, dmd.dscope.Scope*, dmd.root.array.Array!(dmd.expression.Expression).Array*)+0xcc3) [0x585f3b]
dmd(void dmd.dtemplate.functionResolve(dmd.declaration.Match*, dmd.dsymbol.Dsymbol, dmd.globals.Loc, dmd.dscope.Scope*, dmd.root.array.Array!(dmd.root.rootobject.RootObject).Array*, dmd.mtype.Type, dmd.root.array.Array!(dmd.expression.Expression).Array*, const(char)**)+0x148) [0x58b760]
dmd(_Z15resolveFuncCallRK3LocP5ScopeP7DsymbolP5ArrayIP10RootObjectEP4TypePS6_IP10ExpressionEi+0xd1) [0x5ca761]
dmd(_ZN25ExpressionSemanticVisitor5visitEP7CallExp+0x2504) [0x5b3d14]
dmd(_ZN7CallExp6acceptEP7Visitor+0x1d) [0x5a6b7d]
dmd(_Z18expressionSemanticP10ExpressionP5Scope+0x43) [0x5c38fb]
dmd(_ZN24StatementSemanticVisitor5visitEP12ExpStatement+0x50) [0x63d278]
dmd(_ZN12ExpStatement6acceptEP7Visitor+0x1d) [0x622d1d]
dmd(_Z17statementSemanticP9StatementP5Scope+0x43) [0x63d19b]
dmd(_ZN24StatementSemanticVisitor5visitEP17CompoundStatement+0xe8) [0x63d518]
dmd(_ZN17CompoundStatement6acceptEP7Visitor+0x1d) [0x62344d]
dmd(_Z17statementSemanticP9StatementP5Scope+0x43) [0x63d19b]
dmd(_ZN16Semantic3Visitor5visitEP15FuncDeclaration+0x1174) [0x6504dc]
dmd(_ZN15FuncDeclaration6acceptEP7Visitor+0x1d) [0x5c9fd5]
dmd(_Z9semantic3P7DsymbolP5Scope+0x3d) [0x64ef7d]
dmd(_ZN16Semantic3Visitor5visitEP16TemplateInstance+0x14f) [0x64f0f7]
dmd(_ZN16TemplateInstance6acceptEP7Visitor+0x1d) [0x596845]
dmd(_Z9semantic3P7DsymbolP5Scope+0x3d) [0x64ef7d]
dmd(_ZN16TemplateInstance12trySemantic3EP5Scope+0x5c) [0x59680c]
dmd(void dmd.dsymbolsem.templateInstanceSemantic(dmd.dtemplate.TemplateInstance, dmd.dscope.Scope*, dmd.root.array.Array!(dmd.expression.Expression).Array*)+0xac9) [0x585d41]
dmd(void dmd.dtemplate.functionResolve(dmd.declaration.Match*, dmd.dsymbol.Dsymbol, dmd.globals.Loc, dmd.dscope.Scope*, dmd.root.array.Array!(dmd.root.rootobject.RootObject).Array*, dmd.mtype.Type, dmd.root.array.Array!(dmd.expression.Expression).Array*, const(char)**)+0x148) [0x58b760]
dmd(_Z15resolveFuncCallRK3LocP5ScopeP7DsymbolP5ArrayIP10RootObjectEP4TypePS6_IP10ExpressionEi+0xd1) [0x5ca761]
dmd(_ZN25ExpressionSemanticVisitor5visitEP7CallExp+0x2504) [0x5b3d14]
dmd(_ZN7CallExp6acceptEP7Visitor+0x1d) [0x5a6b7d]
dmd(_Z18expressionSemanticP10ExpressionP5Scope+0x43) [0x5c38fb]
dmd(_ZN24StatementSemanticVisitor5visitEP12ExpStatement+0x50) [0x63d278]
dmd(_ZN12ExpStatement6acceptEP7Visitor+0x1d) [0x622d1d]
dmd(_Z17statementSemanticP9StatementP5Scope+0x43) [0x63d19b]
dmd(_ZN24StatementSemanticVisitor5visitEP17CompoundStatement+0xe8) [0x63d518]
dmd(_ZN17CompoundStatement6acceptEP7Visitor+0x1d) [0x62344d]
dmd(_Z17statementSemanticP9StatementP5Scope+0x43) [0x63d19b]
dmd(_ZN16Semantic3Visitor5visitEP15FuncDeclaration+0x1174) [0x6504dc]
dmd(_ZN15FuncDeclaration6acceptEP7Visitor+0x1d) [0x5c9fd5]
dmd(_Z9semantic3P7DsymbolP5Scope+0x3d) [0x64ef7d]
dmd(_ZN16Semantic3Visitor5visitEP6Module+0x6a) [0x64f31a]
dmd(_ZN6Module6acceptEP7Visitor+0x1d) [0x553055]
dmd(_Z9semantic3P7DsymbolP5Scope+0x3d) [0x64ef7d]
dmd(int dmd.mars.tryMain(ulong, const(char)**)+0x2151) [0x5f1491]
dmd(_Dmain+0x27) [0x5f238f]
dmd(_D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ6runAllMFZ9__lambda1MFZv+0x1f) [0x73626b]
dmd(void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).tryExec(scope void delegate())+0x2a) [0x7361c6]
dmd(void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).runAll()+0x2b) [0x736227]
dmd(void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).tryExec(scope void delegate())+0x2a) [0x7361c6]
dmd(_d_run_main+0x1d2) [0x736146]
dmd(main+0x14) [0x5f6074]
Comment #2 by razvan.nitu1305 — 2023-05-09T11:02:10Z
Further reduced:
======================
template f1(alias fun)
{
struct UnusedButConflicting
{
}
auto f1()
{
}
}
template f2(T)
{
alias fun = {};
auto f2(auto ref T)
{
f1!fun();
}
}
void main()
{
int a;
f2(5);
f2(a);
}
==========================
The problem here comes from the way dmd stores types. It essentially creates a decoration by getting the mangled name of the type. In this case f2 creates different template instances depending on whether f2 is called with an lvalue or an rvalue (due to the presence of auto ref). Having 2 template instances, this leads to having 2 f1 template instances due to `fun` being declared twice in 2 different scopes, although the type is the same.
When semantic is performed on the unused struct the compiler tries to get a unique identifier for the struct type by generating the mangled type. However, the mangling is performing only by taking into account types. Since for both template instances the type of the alias parameter is the same is the same (although the value is different), the mangling ends up being the same, however, the declarations are different, hence the error.
It seems that using the type for alias template parameters to generate the mangling for such declarations is not a correct solution.
Comment #3 by razvan.nitu1305 — 2023-05-09T11:07:06Z
This looks to me like a dupe of: https://issues.dlang.org/show_bug.cgi?id=19024 . Although the issues appears as being fixed, I think that the fix was just a hack that masks the true issue: using mangling names as type decorators does not work for template alias parameters.
Comment #4 by razvan.nitu1305 — 2023-05-11T11:28:55Z
*** Issue 17653 has been marked as a duplicate of this issue. ***
Comment #5 by robert.schadek — 2024-12-13T19:28:44Z