On 4/13/18 7:00 PM, Jonathan Marler wrote:
@Steven You're just addressing the example I gave and not thinking of
all the other ways version (or other compiler flags) could change
things. For example, you could have version code inside a template that
changes mangling because it is no longer inferred to be pure/safe/whatever.
Yeah, but that results in a linker error. Your solution results in a
linker error as well. Either way, you need to adjust your build. Trying
to make the liner spit out a nice error is an exercise in futility.
The point is, this is a solvable problem. All we need to do is save the
compiler configuration (i.e. versions/special flags that affects
compilation) used when compiling a library and use that information when
we are interpreting the module's source as as an "pre-compiled import".
Interpreting a module with a different version than was compiled can
create any error you can possibly come up with and could manifest at any
time (i.e. compile-time, link time, runtime).
int libraryFunction(int x)
// do it the specialized way
// do it the slow way
Do we need to penalize user code that doesn't define the library-special
version UseSpecializedMethod? Making code not link because it didn't
define library specific implementation details the same as the library
isn't going to help.
The jist is that if we don't solve this, then it's up to the
applications to use the same versions that were used to compile all
their pre-compiled D libraries...and if they don't...all bets are off.
They could run into any error at any time and the compiler/type system
can't help them.
For versions, it only makes a difference if the versions affect the
public API (and in a silent way). I'm fine with linker errors to
Note: it's really bad form to make a library who has public API changes
when you define different versions. It's why I'm trying to eliminate all
of those cases for version(unittest) from phobos.
For compiler features, if you get different symbols from the exact same
code (in other words, ALL code involved is exactly the same), then it
may be useful to embed such a compilation linker mechanism to give a
somewhat better linker error. For example, with dip1000, if a library
function using dip1000 adds an attribute that normally wouldn't be
added, you could include such a symbol, and then the linker failure
would show that symbol missing (and hopefully clue in the user).
But even this has drawbacks -- what if you never call that function? Now
you are having a linker error where there normally wouldn't be.
But there are actually a couple real ways to solve this, and they aren't
simple. One is to invent our own linker/object format that allows
embedding the stuff we want. Then you don't import source, you import
the object (this is similar to Java).
The second is to actually spit out a specialized import file that puts
the right attributes/definitions on the public API (and should include
any implementation that needs to be inlined or templated).