[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