Bug 6318 – module isn't fully processed under weird conditions
Status
RESOLVED
Resolution
WORKSFORME
Severity
normal
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
x86_64
OS
Linux
Creation time
2011-07-14T10:47:22Z
Last change time
2020-03-21T03:56:38Z
Assigned to
No Owner
Creator
Trass3r
Comments
Comment #0 by hoganmeier — 2011-07-14T10:47:22Z
One of the weirdest bugs I've ever encountered.
Set up a directory named 'basic'. Inside there 3 files:
module basic.Messages;
//import basic.utils; // for flattenNamedEnum
pragma(msg, "foo");
enum Severity
{
NOTE,
}
pragma(msg, flattenNamedEnum!Severity);
pragma(msg, "bar");
// definition of enum Msg is normally mixed in here
====
module basic.Bar;
import basic.Handle;
import basic.Messages;
class Bar
{
public:
enum Level
{
Ignored,
}
void bla(Msg msg)
{
}
}
====
module basic.Handle;
import basic.Bar;
void foo(Bar.Level level)
{
}
I compiled it from inside the folder with 'dmd -c -I.. Bar.d Handle.d'
Bar.d(13): Error: undefined identifier Msg
foo
Note how basic.Messages is only evaluated to a certain degree.
The same happens with
dmd -c -I.. Bar.d Handle.d Messages.d
dmd -c -I.. Bar.d Messages.d Handle.d
Only with 'dmd -c -I.. Handle.d Bar.d' it yields
foo
../basic/Messages.d(14): Error: template instance template 'flattenNamedEnum' is not defined
__error
bar
Bar.d(16): Error: undefined identifier Msg
And with 'dmd -c -I.. Messages.d Bar.d Handle.d':
foo
Messages.d(14): Error: template instance template 'flattenNamedEnum' is not defined
__error
bar
Bar.d(16): Error: undefined identifier Msg
Also note that adding the definition of Msg by hand like
enum Msg { f }
or commenting out the flattenNamedEnum mixin also shows similar results.
Can anyone confirm this?
Comment #1 by hoganmeier — 2011-07-14T16:09:47Z
Well, if ever needed, here's basic.utils:
//! bring named enum members into current scope
string flattenNamedEnum(EnumType)()
if (is (EnumType == enum))
{
string s = "";
foreach (i, e; __traits(allMembers, EnumType))
{
s ~= "alias " ~ EnumType.stringof ~ "." ~ __traits(allMembers, EnumType)[i] ~ " " ~ __traits(allMembers, EnumType)[i] ~ ";\n";
}
return s;
}
Pulling enum Level out of Bar also seems to 'resolve' this.
Comment #2 by hoganmeier — 2011-07-15T05:00:51Z
And for completeness the Msg generation from basic.Messages:
private immutable records =
[
["bla", "blub"],
];
mixin (generateMsgEnum());
private string generateMsgEnum()
{
string res = " enum Msg : string\n{\n";
foreach (msg; .messageRecords)
res ~= " " ~ msg[0] ~ " = `" ~ msg[1] ~ "`,\n";
res ~= "}\n";
return res;
}
Comment #3 by hoganmeier — 2011-07-15T05:11:03Z
If this has to do with dmd exiting early because of errors, why is there no "fatal error: too many errors occured"?
If it has to do with the cyclic import, why is Messages affected by that? In the import graph it is a sink (or source, depending on how you define the directions).
(Of course utils will be the sink if you include it, but that doesn't change much)
Comment #4 by johannes.loher — 2018-05-05T14:24:57Z
I don't know when this has been fixed, but with 2.080.0, I get both error messages in all cases:
dmd -c -I.. Bar.d Handle.d
Bar.d(13): Error: undefined identifier Msg
foo
../basic/Messages.d(11): Error: template instance `flattenNamedEnum!Severity` template flattenNamedEnum is not defined
../basic/Messages.d(11): while evaluating pragma(msg, flattenNamedEnum!Severity)
bar
dmd -c -I.. Bar.d Handle.d Messages.d
Bar.d(13): Error: undefined identifier Msg
foo
Messages.d(11): Error: template instance `flattenNamedEnum!Severity` template flattenNamedEnum is not defined
Messages.d(11): while evaluating pragma(msg, flattenNamedEnum!Severity)
bar
dmd -c -I.. Bar.d Messages.d Handle.d
Bar.d(13): Error: undefined identifier Msg
foo
Messages.d(11): Error: template instance `flattenNamedEnum!Severity` template flattenNamedEnum is not defined
Messages.d(11): while evaluating pragma(msg, flattenNamedEnum!Severity)
bar
dmd -c -I.. Handle.d Bar.d
foo
../basic/Messages.d(11): Error: template instance `flattenNamedEnum!Severity` template flattenNamedEnum is not defined
../basic/Messages.d(11): while evaluating pragma(msg, flattenNamedEnum!Severity)
bar
Bar.d(13): Error: undefined identifier Msg
dmd -c -I.. Bar.d Messages.d Handle.d
Bar.d(13): Error: undefined identifier Msg
foo
Messages.d(11): Error: template instance `flattenNamedEnum!Severity` template flattenNamedEnum is not defined
Messages.d(11): while evaluating pragma(msg, flattenNamedEnum!Severity)
bar
As this seems to work correctly, I'm closing this.
Comment #5 by b2.temp — 2018-05-05T18:49:14Z
Please use WORKSFORME as resolution when you see it works now but don't know exactly why or which PR solved the issue.