With the patch in bugzilla #461 ( http://d.puremagic.com/issues/show_bug.cgi?id=461 ) applied, you get the expected output:

test.d(1): Error: version v1 defined after use
no

version and debug conditions are analyzed and expanded before any other semantic analysis in a module. I think, versions are defined and limited enough, so you get what you can expect.

But your point holds, if you replace version in your example with static if conditions. These need semantic analysis and this is done (mostly) in lexical order. A forward reference to an identifier defined inside the static if fails, because the identifiers inside a static if are only known in the given scope after evaluating the condition. There are also entries to that effect in bugzilla (e.g. http://d.puremagic.com/issues/show_bug.cgi?id=3743 ) Even worse, declarations inside a static if can change an overload-set, so you might not get an error, but unexpected calls that are very hard to track down.

Similar problems can occur with mixins. I'm not sure CTFE falls into the same category, as it does not generate declarations by itself, it helps evaluating conditions or strings for mixins.

Here's my current guess, how to allow forward references in most cases: when the compiler "visits" a scope (module, class, etc.) due to normal semantic analysis or identifier lookup, compile-time conditions and mixins at the same nesting-level must be evaluated *before anything else* in this scope. A static if condition or mixin must not reference an identifier declared inside a condition or mixin later.

Rainer

Jerry Quinn wrote:
What should happen when the following code is compiled?

mixin(vs);
version(v1) {
  const string vs = "version = v2;";
  pragma(msg, "yes");
}
 else {
  const string vs = "version = v1;";
  pragma(msg, "no");
 }

Currently, there's an error saying that vs must be a string.  However, as far 
as I can tell, the spec says nothing about order affecting module-scope 
declarations.  So vs should be valid, and once it substitutes in the mixin, you 
have a cycle where no matter what vs is, vs should be the other value.

If you don't have the conditional compilation and put the declaration of vs 
after the mixin, it works as expected.

This generally raises the question of what should be the order of evaluation 
for constructs like mixins, conditional compilation, and CTFE.   Each has the 
potential to modify the other.

What should be the rule to break the ambiguity?  Or do we leave it 
implementation-defined?

Thoughts?
Jerry

Reply via email to