Possible solution for export : `unittest export`?

deadalnix via Digitalmars-d digitalmars-d at puremagic.com
Mon Aug 31 18:40:27 PDT 2015


On Sunday, 30 August 2015 at 14:08:15 UTC, Dicebot wrote:
> Follow-up to old 
> http://forum.dlang.org/thread/m9lhc3$1r1v$1@digitalmars.com 
> thread by Benjamin
>
> Short reminder of the issue:
>
> Currently unsolved issue with finishing `export` implementation 
> is lack of convenient semantics for its interaction with 
> templates. If template function is marked as `export`, its 
> non-template dependencies (called functions) will also need to 
> be marked as effectively export (even if private) to be put in 
> object file and avoid linker errors.
>
> Which is impossible to do automatically because dependencies 
> can't be figured out without instantiaton. And to do it 
> manually you'd need to mark all dependencies with `export` too 
> which is impossible without making them also public because 
> currently `export` is defined as protection attribute. One of 
> Benjamin proposals was to split it as a separate attribute kind 
> but doing all manual annotation would still be hardly 
> convenient / maintainable.
>
> Proposal essentials:
>
> Define `unittest export { /* tests here */ }` which will verify 
> that all directly used symbols from same module/package are 
> marked as export and automatically mark dependencies for 
> placement into object files while doing semantic phase for 
> tested instances.
>
> Rationale:
>
> - fits existing "documented unittest" feature by providing 
> verified example of using the API
> - easier change to grammar than re-defining export itself
> - reasonably simple maintenance (no need to hunt each small 
> dependency function after internal changes, risking linker 
> errors if sloppy)
> - if https://issues.dlang.org/show_bug.cgi?id=14825 is ever 
> fixed, combining this with -cov will ensure reasonable 
> confidence in proper API annotation
>
> Cons:
>
> - implies test author to be smart enough to do all necessary 
> instantiations (will become less of an issue with 
> https://issues.dlang.org/show_bug.cgi?id=14825)
> - may look like a hack for those coming from more restrictive 
> languages

I don't really understand the proposal. Let me try to rephrase 
what I do get, and I'll let you fill in.

We want to have method that are not export to be, not exported. 
It allow the optimizer to do more, make executable slimmer and so 
on.

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 ?

Good, then, what is the solution ?

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.


More information about the Digitalmars-d mailing list