Skip to content

Commit 612546d

Browse files
committed
Merge remote-tracking branch 'origin/dmd-rewrite-stable' into merge_stable
2 parents f241166 + 24d5387 commit 612546d

File tree

4 files changed

+37
-5
lines changed

4 files changed

+37
-5
lines changed

dmd/expressionsem.d

+1-1
Original file line numberDiff line numberDiff line change
@@ -5588,7 +5588,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
55885588
symtab = sds.symtab;
55895589
}
55905590
assert(symtab);
5591-
Identifier id = Identifier.generateIdWithLoc(s, exp.loc);
5591+
Identifier id = Identifier.generateIdWithLoc(s, exp.loc, cast(string) toDString(sc.parent.toPrettyChars()));
55925592
exp.fd.ident = id;
55935593
if (exp.td)
55945594
exp.td.ident = id;

dmd/identifier.d

+13-4
Original file line numberDiff line numberDiff line change
@@ -211,11 +211,14 @@ nothrow:
211211
* Params:
212212
* prefix = first part of the identifier name.
213213
* loc = source location to use in the identifier name.
214+
* parent = (optional) extra part to be used in uniqueness check,
215+
* if (prefix1, loc1) == (prefix2, loc2), but
216+
* parent1 != parent2, no new name will be generated.
214217
* Returns:
215218
* Identifier (inside Identifier.idPool) with deterministic name based
216219
* on the source location.
217220
*/
218-
extern (D) static Identifier generateIdWithLoc(string prefix, const ref Loc loc)
221+
extern (D) static Identifier generateIdWithLoc(string prefix, const ref Loc loc, string parent = "")
219222
{
220223
// generate `<prefix>_L<line>_C<col>`
221224
OutBuffer idBuf;
@@ -234,14 +237,20 @@ nothrow:
234237
* https://issues.dlang.org/show_bug.cgi?id=18880
235238
* https://issues.dlang.org/show_bug.cgi?id=18868
236239
* https://issues.dlang.org/show_bug.cgi?id=19058
240+
*
241+
* It is a bit trickier for lambdas/dgliterals: we want them to be unique per
242+
* module/mixin + function/template instantiation context. So we use extra parent
243+
* argument for that when dealing with lambdas. We could have added it to prefix
244+
* directly, but that would unnecessary lengthen symbols names. See issue:
245+
* https://issues.dlang.org/show_bug.cgi?id=23722
237246
*/
238-
static struct Key { Loc loc; string prefix; }
247+
static struct Key { Loc loc; string prefix; string parent; }
239248
__gshared uint[Key] counters;
240249

241250
static if (__traits(compiles, counters.update(Key.init, () => 0u, (ref uint a) => 0u)))
242251
{
243252
// 2.082+
244-
counters.update(Key(loc, prefix),
253+
counters.update(Key(loc, prefix, parent),
245254
() => 1u, // insertion
246255
(ref uint counter) // update
247256
{
@@ -253,7 +262,7 @@ nothrow:
253262
}
254263
else
255264
{
256-
const key = Key(loc, prefix);
265+
const key = Key(loc, prefix, parent);
257266
if (auto pCounter = key in counters)
258267
{
259268
idBuf.writestring("_");
+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
module imports.test23722_2b;
2+
3+
struct T(alias fun) { }
4+
5+
struct S(int i) {
6+
auto t = T!(x => i)();
7+
}
8+
9+
string g() {
10+
S!0 s0;
11+
S!1 s1;
12+
return s1.t.init.mangleof;
13+
}

tests/dmd/runnable/test23722_2.d

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// COMPILE_SEPARATELY:
2+
// EXTRA_SOURCES: imports/test23722_2b.d
3+
// https://issues.dlang.org/show_bug.cgi?id=23722
4+
// Lambdas are mangled incorrectly when using multiple compilation units, resulting in incorrect code
5+
import imports.test23722_2b;
6+
7+
void main() {
8+
S!1 s1;
9+
assert(s1.t.init.mangleof == g);
10+
}

0 commit comments

Comments
 (0)