another cool RTInfo trick - i want in runtime
Marco Leise
Marco.Leise at gmx.de
Thu Jan 16 12:16:51 PST 2014
Am Thu, 16 Jan 2014 15:57:04 +0000
schrieb "Adam D. Ruppe" <destructionator at gmail.com>:
> Check this out. Modify your druntime slightly. In object.di, find
> template RTInfo(T) and add this bit:
>
> import core.config;
> alias checkResult = TypeCheck!T;
>
> Then, pop open import/core/config.d and put these contents in it:
>
> module core.config;
> template TypeCheck(T) {
> enum TypeCheck = true;
> }
>
>
> Compile a program, any program. Should be no difference in
> anything - no errors, no changes to the binary, no compile
> slowdown - from before the modifications.
>
>
> Now, create a file named anything you want with these contents:
>
> module core.config;
> template TypeCheck(T) {
> static if(T.stringof == "Cool")
> static assert(0, "No type named 'Cool' is allowed!");
> enum TypeCheck = true;
> }
>
>
> Compile your program, should still work. Then add "struct Cool{}"
> to it anywhere... and you get a compile error.
>
>
>
> Brothers and sisters, I've talked to you before about doing
> custom RTInfo using __traits(compiles) tricks to look for the
> config module, but my previous ways - while they worked - sucked
> because the compiler would look for the module over and over
> again, slowing things down a bit.
>
> This new method achieves success on all counts. By offering a
> file with druntime to be the module up front, the compiler does
> no special searching, it finds it. It is a trivial file, so
> impact on compile speed is negligible.
>
> But then, if you offer your own file with the same module name on
> the command line, dmd looks THERE first, finds your special code,
> and knows to skip searching the import path! Even true for
> object.d, since this is all in templates with local imports; the
> template still needs to be instantiated.
>
> Since this object.d doesn't actually store anything* in the
> RTInfo itself, there's no worry of binary incompatibilities
> resulting from separate compiliation with different rtinfo
> modules. It simply provides a hook into the types for checking.
>
> Using this, we can automatically check all kinds of per-project
> requirements. Don't want virtual functions in your class unless
> they are reviewed? Make your TypeCheck loop over them and look
> for a UDA, issuing a static assert if not there. Don't want
> references to un-owned mutable data? Ditto. Have a naming
> convention to check? Can do that too.
>
>
> I see lots of upsides, and the downsides from my last experiment
> with this I believe have been eliminated. Am I missing something?
> I wanna do a druntime pull request!
>
>
> * User data extensions could potentially be allowed if RTInfo
> stored a pointer to an interface, which may be null. Other
> modules may implement the interface differently, but as long as
> they implement it (or set it to null), it should still have
> consistent binary compatibility.
>
> You might make object.d's RTInfo create a static struct with
> information the GC needs first, then a pointer to the user
> defined data. The RTInfo template ultimately resolves to the
> pointer to that struct. The data itself is consistent - still
> defined in only one place, druntime itself, and the GC info is
> available right there, no added indirection, and we have the hook
> for user additions too, all under a consistent interface.
>
> You can also add runtime info about a type using static
> constructors:
> ===
> module core.config;
>
> string[] types;
>
> template TypeCheck(T) {
> enum TypeCheck = true;
>
> shared static this() {
> types ~= T.mangleof;
> }
> }
> ===
> module test500.d
> struct Cool {}
>
> void main() {
> import core.config, std.stdio;
> writeln(types);
> }
> ===
> dmd test500.d rtinfo.d
>
> $ ./test500
> ["S7test5004Cool",
> "S3std5array17__T8AppenderTAyaZ8Appender4Data",
> "S3std5array17__T8AppenderTAyaZ8Appender"]
>
>
> Run time info available about all the types used in that program!
>
>
> Soooo yeah, this is pretty much a pure win all around to my eyes.
> Am I blind to the suck?
This solve quite a few issues at once! It looks like
stuff that could only be done with compiler extensions or AST
manipulations and yet it works with a simple template.
Just for the neat "once in a lifetime" idea it should be
accepted. :)
--
Marco
More information about the Digitalmars-d
mailing list