Code:
-----snip-----
import std.stdio;
import std.algorithm;
void main()
{
int[] arr = [3,4,2,1];
bool less(int a, int b)
{ return a < b; }
bool greater(int a, int b)
{ return a > b; }
{
auto dg = &less;
sort!(dg)(arr);
}
//this dg *should* be different from older destroyed dg
//rename to dg2 and everything works as expected
auto dg = &greater;
sort!(dg)(arr);
writeln(arr);
//outputs [1,2,3,4] instead of [4,3,2,1]
//change dg variable name in either place and it works
//also, if you don't do the 1st sort, it works correctly even with same variable name
}
-----snip-----
Comment #1 by hsteoh — 2014-07-16T16:56:24Z
Looks like the problem is that the mangling of both instances of 'dg' is identical, so the compiler thinks that they are the same function.
Comment #2 by hsteoh — 2014-07-16T17:07:06Z
A slightly simpler test case:
-----
import std.stdio;
void myFunc(alias Sym)()
{
writefln("%s", Sym);
}
void main()
{
{
{
int x = 789;
myFunc!x();
}
int x = 456;
myFunc!x();
}
int x = 123;
myFunc!x();
}
-----
Expected output:
-----
789
456
123
-----
Actual output:
-----
789
789
789
-----
Comment #3 by hsteoh — 2014-07-16T17:32:07Z
A clearly legal case that's currently broken:
----
import std.stdio;
void myFunc(alias Sym)()
{
writeln(Sym);
}
void main()
{
foreach (i; 0..3) {
myFunc!i();
}
foreach (i; 5..8) {
myFunc!i();
}
}
----
Expected output:
----
0
1
2
5
6
7
----
Actual output:
----
0
1
2
2
2
2
----
The two instances of 'i' are clearly in distinct scopes, yet they are conflated in the mangling of myFunc, leading to wrong generated code.
Comment #4 by sludwig — 2015-07-27T12:17:17Z
I assume that this has the same root cause:
---
void checkAlias(X...)(int cmp) { assert(X[0] == cmp); }
void main() {
foreach (j; 0 .. 2) {
if (j == 0) {
int i = 42;
checkAlias!(i)(i); // succeeds (42 == 42)
} else {
int i = 13;
checkAlias!(i)(i); // fails (42 == 13)
}
}
}
---
This is a reduced test case of https://github.com/rejectedsoftware/vibe.d/issues/863
Comment #5 by k.hara.pg — 2015-07-27T13:13:42Z
(In reply to Sönke Ludwig from comment #4)
> I assume that this has the same root cause:
>
> ---
> void checkAlias(X...)(int cmp) { assert(X[0] == cmp); }
>
> void main() {
> foreach (j; 0 .. 2) {
> if (j == 0) {
> int i = 42;
> checkAlias!(i)(i); // succeeds (42 == 42)
> } else {
> int i = 13;
> checkAlias!(i)(i); // fails (42 == 13)
> }
> }
> }
> ---
>
> This is a reduced test case of
> https://github.com/rejectedsoftware/vibe.d/issues/863
Yes, it's same issue.
Comment #6 by k.hara.pg — 2015-07-27T13:14:52Z
*** This issue has been marked as a duplicate of issue 14831 ***
Comment #7 by moonlightsentinel — 2021-02-26T23:47:03Z
@MoonlightSentinel updated dlang/dmd pull request #12236 "Fix 10619 - Wrong local variable passed as alias arguments to templates" fixing this issue:
- Fix 10619 - Wrong local variable passed as alias arguments to templates
PR #12119 introduced `localNum` to differentiate between multiple
symbols with identical names. But `Dsymbol.equals` doesn't consider
this variable when comparing two Dsymbols.
This caused template semantic to treat the second instantiation of
`foo` as a duplice in the following example:
```d
void main()
{
{
int x = 1;
foo!x();
}
{
int x = 2;
foo!x();
}
}
```
https://github.com/dlang/dmd/pull/12236
Comment #9 by dlang-bot — 2021-02-28T12:11:41Z
dlang/dmd pull request #12236 "Fix 10619 - Wrong local variable passed as alias arguments to templates" was merged into stable:
- 9f980f52e6d798c06e6b7da55e12cf25882cc757 by MoonlightSentinel:
Fix 10619 - Wrong local variable passed as alias arguments to templates
PR #12119 introduced `localNum` to differentiate between multiple
symbols with identical names. But `Dsymbol.equals` doesn't consider
this variable when comparing two Dsymbols.
This caused template semantic to treat the second instantiation of
`foo` as a duplice in the following example:
```d
void main()
{
{
int x = 1;
foo!x();
}
{
int x = 2;
foo!x();
}
}
```
https://github.com/dlang/dmd/pull/12236
Comment #10 by dlang-bot — 2021-03-06T03:40:51Z
dlang/dmd pull request #12253 "merge stable" was merged into master:
- 0c2d8bd2abf22476acf98065252559145c481fef by MoonlightSentinel:
Fix 10619 - Wrong local variable passed as alias arguments to templates
PR #12119 introduced `localNum` to differentiate between multiple
symbols with identical names. But `Dsymbol.equals` doesn't consider
this variable when comparing two Dsymbols.
This caused template semantic to treat the second instantiation of
`foo` as a duplice in the following example:
```d
void main()
{
{
int x = 1;
foo!x();
}
{
int x = 2;
foo!x();
}
}
```
https://github.com/dlang/dmd/pull/12253