[dmd-internals] Fixing forward ref bugs for good

Rainer Schuetze r.sagitario at gmx.de
Thu Sep 15 11:34:08 PDT 2011


On 15.09.2011 17:56, Andrei Alexandrescu 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.
>

There is a much easier example against "simultaneous" static-if evaluation:

static if(size_t.sizeof == 8)
     enum is64bit = true;
else
     enum is64bit = false;

// later in the same module:
static if(is64bit)
{
}

will not compile because is64bit is not defined while all static ifs are 
evaluated.

> 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.
>

My proposal does not have this problem: all static ifs and mixins at the 
level of the scope are expanded in lexical order before it is searched 
(including enumeration). Problems might arise with circular symbol 
definitions: If evaluating the condition needs lookup of a symbol in the 
same scope, should that lookup force expanding later static-ifs and 
mixins or should it just work with the symbols available when starting 
evaluating the initial static-if? I think the latter seems better, 
because it is easier to understand.

class X
{
     static if(A.sizeof > 4) // will result in error if "static if(1)" 
below is not expanded during evaluation
         int a;

     static if(1)   // should this static-if be expanded while 
evaluating A.sizeof?
         enum N = 1;
     else
         enum N = 2;

     alias int[N] A; // error: undefined "N"?
}

There are corner cases that fail with this approach, but might compile 
with the "try again" approach, though with almost unpredictable results:

class C
{
     static if(is(typeof(A)))
         alias int B;
     static if(!is(typeof(B)))
         alias int A;

     B b;
}



More information about the dmd-internals mailing list