Bug 17441 – std.traits.moduleName gives wrong answer for modules imported under a different name in a mixin
Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P1
Component
phobos
Product
D
Version
D2
Platform
All
OS
All
Creation time
2017-05-27T01:00:38Z
Last change time
2020-02-07T04:15:18Z
Keywords
pull
Assigned to
No Owner
Creator
Atila Neves
Comments
Comment #0 by atila.neves — 2017-05-27T01:00:38Z
To reproduce:
main.d:
import std.traits;
import std.stdio;
void moduleStrings(T...)() {
import std.conv: to;
import std.range: iota;
import std.algorithm: map;
import std.array: join;
string getModulesString() {
string[] modules;
foreach(i, module_; T)
modules ~= `mod` ~ i.to!string ~ ` = ` ~ module_;
return modules.join(", ");
}
mixin(`import ` ~ getModulesString ~ `;`);
mixin(`moduleSymbols!(` ~ T.length.iota.map!(i => `mod` ~ i.to!string).join(", ") ~ `);`);
}
void moduleSymbols(T...)() {
import std.meta;
foreach(t; AliasSeq!T) {
writeln(moduleName!t);
}
}
void main() {
moduleStrings!("foo.bar.baz", "foo.bar");
}
foo/bar/package.d:
module foo.bar;
foo/bar/baz.d:
module foo.bar.baz;
The above program prints:
foo.bar.baz
foo.bar.bar
The 2nd entry is a non-existing module, since there are only two: `foo.bar.baz` and `foo.bar`.
As I looked into it, the problem seems to be T.stringof when T is a package:
import foo.bar;
pragma(msg, foo.bar.stringof); // "package bar"
import oops = foo.bar;
pragma(msg, oops.stringof); // "module bar"
std.traits.moduleName actually looks at .stringof and makes decisions based on whether or not it starts with the word "module".
Comment #1 by bugzilla — 2020-01-10T14:09:04Z
Mixin seems not to matter. Simplified testcase (foo/bar/package.d and foo/bar/baz.d like above):
void main()
{
import std.traits : moduleName;
import mod0 = foo.bar.baz;
import mod1 = foo.bar;
assert(moduleName!mod0 == "foo.bar.baz");
assert(moduleName!mod1 == "foo.bar"); // fails with foo.bar.bar
}
Comment #2 by bugzilla — 2020-01-10T14:45:28Z
The problem is the call to packageName, not moduleName:
void main()
{
import std.traits : packageName;
import mod0 = foo.bar.baz;
import mod1 = foo.bar;
assert(packageName!mod0 == "foo.bar"); // comment this line out and it works
assert(packageName!mod1 == "foo"); // fails with foo.bar
}
It seems, that the template `packageName` is only instantiated with the first call. For the second, the template parameter seems to be considered the same as before (although it isn't). DMD bug?
Comment #3 by bugzilla — 2020-01-11T08:29:34Z
*** This issue has been marked as a duplicate of issue 14501 ***
Comment #4 by boris2.9 — 2020-01-15T06:29:14Z
Although similar to issue 14501 this doesn't deal with enums (that seems more hard to fix).
I have a working solution for the examples except the Atila's last part:
import foo.bar;
pragma(msg, foo.bar.stringof); // "package bar"
import oops = foo.bar;
pragma(msg, oops.stringof); // "module bar"
which I think belongs to another bug report.
Comment #5 by dlang-bot — 2020-01-15T06:54:28Z
@BorisCarvajal created dlang/dmd pull request #10724 "Fix Issue 17441 - Template instantiation reused when arguments are mo…" fixing this issue:
- Fix Issue 17441 - Template instantiation reused when arguments are module and package with same name
https://github.com/dlang/dmd/pull/10724
Comment #6 by dlang-bot — 2020-01-19T04:05:13Z
dlang/dmd pull request #10724 "Fix Issue 17441 - Template instantiation reused when arguments are mo…" was merged into stable:
- 909f8db921ac52669c0a2832408b21ca12743112 by Boris Carvajal:
Fix Issue 17441 - Template instantiation reused when arguments are module and package with same name
https://github.com/dlang/dmd/pull/10724
Comment #7 by dlang-bot — 2020-02-07T04:15:18Z
dlang/dmd pull request #10753 "Merge remote-tracking branch 'upstream/stable' into merge_stable" was merged into master:
- b7c279fe6069b73569f781d7dbedb2ff100f546d by Boris Carvajal:
Fix Issue 17441 - Template instantiation reused when arguments are mo… (#10724)
Fix Issue 17441 - Template instantiation reused when arguments are mo…
merged-on-behalf-of: Nicholas Wilson <[email protected]>
https://github.com/dlang/dmd/pull/10753