[dmd-internals] Fixing forward ref bugs for good

Don Clugston dclugston at googlemail.com
Thu Sep 15 23:04:38 PDT 2011


On 15 September 2011 17:56, Andrei Alexandrescu <andrei at erdani.com> wrote:
> On 9/15/11 6:53 AM, Don Clugston wrote:
>>
>> On 15 September 2011 13:14,<mrmocool at gmx.de>  wrote:
>>>
>>> Am 15.09.2011, 11:44 Uhr, schrieb Don Clugston<dclugston at googlemail.com>:
>>>>
>>>> I think there is a simple solution to 'static if'.
>>>> Do const folding on every static if condition, giving a boolean result.
>>>> Do NOT evaluate any static if bodies yet.
>>>> This would have the same effect as if every 'static if' were evaluated
>>>> simultaneously.
>>>
>>> What if the condition includes symbols from another static if's body or
>>> mixin or whatever?
>>
>> I think that should be disallowed.
>
> I see an issue here with cross-module use. For example, it's nice to have:
>
> import some.module;
>
> static if (is(typeof(some.module.foobar) == int)) {
>   alias some.module.foobar baz;
> } else {
>   enum baz = 42; // or whatever
> }
>
> So far so good. The problem now is that some.module uses a similar technique
> to introduce that symbol foobar, the code won't work anymore.
>
> I also realized that code relying on enumerating symbols in a module (like
> benchmark does) or a class (like an introspection library does) will miss
> all symbols guarded by static if. And, for example, ranges define plenty of
> those. This erodes the power of static if substantially.

Not so. The thing is, static ifs can be nested. Only one level of
static if is removed at a time.
If you simply wrap the static if inside static if(true) {...}
it won't be evaluated until all the first-level static ifs have added
their symbols to the scope.

So the current:
static if (cond1)
{
    A;
}
static if (cond2)
{
   B;
}
where cond2 depends on A, can be rewritten in the 'parallel execution'
paradigm as:
static if (cond1)
{
    A;
}
static if (true)
{
  static if (cond2)
  {
     B;
  }
}
Order of execution is controlled by depth of nesting, instead of by
order in the file.
Note that in your first example, the question of which module
instantiates the symbol is determined not even by order within the
file, but by which module is first on the command line -- ie, it's
determined by the makefile!


More information about the dmd-internals mailing list