Thread overview
Forward Reference Error in unittests
Dec 03, 2019
rbscott
Dec 03, 2019
mipri
Dec 03, 2019
MoonlightSentinel
Dec 04, 2019
rbscott
December 03, 2019
Hello,

I was using a unittest to test a mixin that creates a class inside of a struct and I ran into an unexpected error. I removed all of the templates and simplified it down to this case:

unittest {
  static struct SimpleStruct {
    static class NestedClass {
      private SimpleStruct value;
    }
  }
}

For some reason this generates a forward reference error, but if I take the exact same code and declare it outside of a unittest it goes away. If it runs in a version block instead of a unittest block it also works? I think declaring structs is OK in unittests? I tested this with:

unittest {
  static struct SimpleStruct {
    static class NestedClass {
      private int value;
    }
  }
}

And this works fine. Any ideas about why this doesn't work in a unittest?

Thanks!
rbscott

December 03, 2019
On Tuesday, 3 December 2019 at 08:48:47 UTC, rbscott wrote:
> Hello,
>
> I was using a unittest to test a mixin that creates a class inside of a struct and I ran into an unexpected error. I removed all of the templates and simplified it down to this case:
>
> unittest {
>   static struct SimpleStruct {
>     static class NestedClass {
>       private SimpleStruct value;
>     }
>   }
> }

Unit tests are special functions, and their contents have
the same restrictions of functions, which seem to include
a ban on forward references (there's a reference in a comment
in https://dlang.org/spec/function.html#nested but I don't
have a better citation).

Likewise this fails, but would succeed if foo were moved
out of the unit test:

unittest {
    void foo(int x) { writeln(x); }

    42.foo;
}

December 03, 2019
On Tuesday, 3 December 2019 at 10:30:34 UTC, mipri wrote:

> Likewise this fails, but would succeed if foo were moved
> out of the unit test:
>
> unittest {
>     void foo(int x) { writeln(x); }
>
>     42.foo;
> }

Not a forward reference error, local symbols are excluded from UFCS (see https://dlang.org/spec/function.html#pseudo-member)
December 04, 2019
On Tuesday, 3 December 2019 at 11:31:40 UTC, MoonlightSentinel wrote:
> On Tuesday, 3 December 2019 at 10:30:34 UTC, mipri wrote:
>
>> Likewise this fails, but would succeed if foo were moved
>> out of the unit test:
>>
>> unittest {
>>     void foo(int x) { writeln(x); }
>>
>>     42.foo;
>> }
>
> Not a forward reference error, local symbols are excluded from UFCS (see https://dlang.org/spec/function.html#pseudo-member)

I see, thanks for the explanation about unittests being a special case of functions. That is really helpful context and makes sense since functions should evaluate sequentially. A little surprised the same restrictions apply to a static struct declared inside of the unittest, but that is easy to work around by moving the declarations to the version section.

cheers,
rbscott