@@ -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(" _" );
0 commit comments