[Issue 20443] Case where code compiles depending on order of declaration

d-bugmail at puremagic.com d-bugmail at puremagic.com
Thu Dec 12 10:08:30 UTC 2019


https://issues.dlang.org/show_bug.cgi?id=20443

--- Comment #4 from Walter Bright <bugzilla at digitalmars.com> ---
https://github.com/pbackus/sumtype/issues/35#issuecomment-563452054 reproduced
here for convenience:

------------------------------

Here's my best attempt at an explanation:

During semantic analysis of CallbackType1, the forward reference to Class1
triggers on-demand semantic analysis of Class1, which in turn triggers
on-demand semantic analysis of SumType!CallbackType1.

Normally, this would trigger on-demand analysis of CallbackType1, but the
compiler notices it's already started analyzing CallbackType1 and terminates
the recursion.

While analyzing SumType!CallbackType1, the compiler evaluates
isCopyable!CallbackType1. The source code for isCopyable looks like this:

enum isCopyable(S) = is(typeof(
    { S foo = S.init; S copy = foo; }
));
When the lambda inside isCopyable attempts to declare an instance of
CallbackType1 as a local variable, it fails, because semantic analysis of
CallbackType1 is still in progress and its size is not yet known. You can
verify this by copy & pasting the lambda above into the reduced version of
SumType, before the static if statement. Doing so will produce the following
error:

Error: struct `onlineapp.CallbackType1` no size because of forward reference
Because of this error, compilation of the lambda fails, and
isCopyable!CallbackType1 evaluates to false.

Swapping the order of the declarations fixes the issue because it changes DMD's
semantic-analysis "call stack" from this:

CallbackType1 → Class1 → SumType!CallbackType1

to this:

Class1 → SumType!CallbackType1 → CallbackType1

As long as SumType!CallbackType1 is encountered before CallbackType1, DMD is
able to finish analyzing CallbackType1 before it evaluates
isCopyable!CallbackType1, and thus does not encounter the error described
above.

Fixing this in DMD is likely to be quite difficult. However, it may be possible
to find a workaround for isCopyable that allows it to work with incomplete
types.

--


More information about the Digitalmars-d-bugs mailing list