Possible solution for export : `unittest export`?

Dicebot via Digitalmars-d digitalmars-d at puremagic.com
Mon Aug 31 18:52:21 PDT 2015


On Tuesday, 1 September 2015 at 01:40:29 UTC, deadalnix wrote:
> Problem arise with templates, for instance:
>
> export void foo(T)(T t) { bar(); }
>
> private void bar() { import std.stdio; writeln("bar was 
> called"); }
>
> Here bar is called. Problem is, foo can be instantiated in a 
> different module than bar is compiled in. As bar is not 
> exported, things will fail to link.
>
> When compiling the module with bar, foo is not instantiated and 
> the compiler has no way to know that this template may use bar 
> (the template is simple here but it could be arbitrarily 
> complex in practice).
>
> Am I right so far ?

Yep, got it exactly right.


> Good, then, what is the solution ?

Something like this

Error : template foo is marked as export but not instantiated 
within any unittest export

To fix, add API test / example:

unittest export {
     foo(42);
}

Compiler sees that unittest export has created `foo!int` and 
checks what
non-template functions get called from that instance (I may be 
mistaken but
all necessary information for that is known once we have actual 
instance
for an argument set).

Of course, if some branches are missing in unittest export, it 
will still
cause linker errors - that is why fixing linked issue with 
coverage becomes
pretty important.

> Note that this is a reason why I like trait or whatever so that 
> the compiler can figure out what is going on in the template 
> before instantiating it. I tried this road with SDC at first, 
> but the amount of infos that the compiler can infer from D 
> template is way too small for it to be worth it.

Yep, this is why I feel that such a solution will feel dirty if 
you get
used to something like traits which allows for full analysis 
without
instantiating. But within existing semantics it does not seem 
possible,
it simply allows too much.


More information about the Digitalmars-d mailing list