www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 17441] New: std.traits.moduleName gives wrong answer for

https://issues.dlang.org/show_bug.cgi?id=17441

          Issue ID: 17441
           Summary: std.traits.moduleName gives wrong answer for modules
                    imported under a different name in a mixin
           Product: D
           Version: D2
          Hardware: x86_64
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P1
         Component: phobos
          Assignee: nobody puremagic.com
          Reporter: atila.neves gmail.com

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".

--
May 26