D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 6318 - module isn't fully processed under weird conditions
Summary: module isn't fully processed under weird conditions
Status: RESOLVED WORKSFORME
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: x86_64 Linux
: P2 normal
Assignee: No Owner
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-07-14 10:47 UTC by Trass3r
Modified: 2020-03-21 03:56 UTC (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Trass3r 2011-07-14 10:47:22 UTC
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 Trass3r 2011-07-14 16:09:47 UTC
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 Trass3r 2011-07-15 05:00:51 UTC
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 Trass3r 2011-07-15 05:11:03 UTC
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 Johannes Loher 2018-05-05 14:24:57 UTC
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 basile-z 2018-05-05 18:49:14 UTC
Please use WORKSFORME as resolution when you see it works now but don't know exactly why or which PR solved the issue.