Currently, compilation will change depending on the order that imports are processed. This order is determined by the order that modules are passed to the compiler on the command line, and also the order they appear in each individual file. Here are some examples:
Import order in file changes output:
--- foo.d
version (A)
{
static import baz;
static import bar;
}
version (B)
{
static import bar;
static import baz;
}
void main()
{
import std.stdio;
writeln(bar.thing);
writeln(baz.thing);
}
--- bar.d
module baz;
enum thing = "this is baz from bar.d";
--- baz.d
module bar;
enum thing = "this is bar from baz.d";
dmd -version=A -run foo.d
----
this is bar from baz.d
this is bar from baz.d
----
dmd -version=B -run foo.d
----
this is baz from bar.d
this is baz from bar.d
----
Output changes depending on order of modules passed on the command line:
--- main.d
import ibar, ibaz;
void main()
{
ibarfunc();
ibazfunc();
}
--- ibar.d
import bar, std.stdio;
void ibarfunc()
{
writeln(thing);
}
--- ibaz.d
import baz, std.stdio;
void ibazfunc()
{
writeln(thing);
}
--- bar.d
module baz;
enum thing = "this is baz from bar.d";
--- baz.d
module bar;
enum thing = "this is bar from baz.d";
dmd ibar.d ibaz.d -run main.d
OUTPUT:
this is baz from bar.d
this is baz from bar.d
dmd ibaz.d ibar.d -run main.d
OUTPUT:
this is bar from baz.d
this is bar from baz.d
A PR to fix this has been submitted: https://github.com/dlang/dmd/pull/7900
Comment #1 by johnnymarler — 2018-05-24T12:36:40Z
Added 2 tests to dmd for this bug here: https://github.com/dlang/dmd/pull/8165 but the PR was rejected. Razvan doesn't think tests should be pushed to dmd by themselves (without their corresponding fixes).
> Razvan: I don't see much benefit in having tests that don't pass in the test suite. This puts a burden on the autotester and encourages people to make PRs just with tests creating a separation between the fix and the test.
Hm... I didn't realize that the module identifier was not identical to the filename. That is interesting. It's not clearly stated in this bug report that this is a requirement to get the error to occur -- I thought it had something to do with the fact that `thing` appears in both files.
I would expect that if a module is loaded via using the filesystem, and the module name doesn't match how it was found, then this should be an error. Anything else seems to strain your sanity!
In other words, if you pass the modules on the command line, then they can have non-matching filenames, but if they were found via the module name mapping to directories, they had better match the module name.
Comment #4 by johnnymarler — 2018-10-30T00:36:26Z
> I would expect that if a module is loaded via using the filesystem, and the module name doesn't match how it was found, then this should be an error. Anything else seems to strain your sanity!
I thought the same, even made a PR to fix this but was told that by Andrei that Walter didn't want to integrate this restriction.
> In other words, if you pass the modules on the command line, then they can have non-matching filenames, but if they were found via the module name mapping to directories, they had better match the module name.
Agreed, but Walter and Andrei do not. I believe this is the PR I created to enforce this, https://github.com/dlang/dmd/pull/7878/files but Walter and Andrei discussed this on their own and decided against it.
The unfortunate consequence is that now no matter what we do, you can get different results if you compile different sets of modules, i.e.
dmd -c foo.d bar.d
can be different than
dmd -c foo.d
dmd -c bar.d
there's no way to make these behave the same with their decision not to enforce this rule. Seems ludicrous to me but not much I can do when they decide to discuss these things behind close doors.
Comment #5 by schveiguy — 2018-10-30T00:54:02Z
I wasn't a part of that conversation, but the "feature" makes no sense -- if you want to import a module and it doesn't reside at the filename that you import, then the system can't find that module. It doesn't make sense that the compiler then "renames" the module after the file name.
Is the conversation listed somewhere on github or the forums? I'd like to reopen that conversation.
Comment #6 by robert.schadek — 2024-12-13T18:57:25Z