Voldemort Types in D

Jonathan M Davis jmdavisProg at gmx.com
Wed May 9 11:00:01 PDT 2012


On Wednesday, May 09, 2012 10:41:31 Adam Wilson wrote:
> On Wed, 09 May 2012 10:19:08 -0700, Jonathan M Davis <jmdavisProg at gmx.com>
> 
> wrote:
> > On Wednesday, May 09, 2012 10:05:36 Adam Wilson wrote:
> >> On Wed, 09 May 2012 08:58:56 -0700, Nicolas Sicard <dransic at gmail.com>
> >> 
> >> wrote:
> >> > On Wednesday, 9 May 2012 at 14:30:33 UTC, Andrei Alexandrescu wrote:
> >> http://www.reddit.com/r/programming/comments/telhj/voldemort_types_in_d/
> >> 
> >> >> Andrei
> >> > 
> >> > One drawback of Voldemort types, is that they are incompatible with
> >> 
> >> the
> >> 
> >> > generation of .di files (option -H).
> >> > 
> >> > See http://d.puremagic.com/issues/show_bug.cgi?id=5461.
> >> > 
> >> > Nicolas
> >> 
> >> This pull fixes this problem and a bunch of others:
> >> https://github.com/D-Programming-Language/dmd/pull/928. However, it
> >> currently fails to build on Linux and fails the unittests on Windows
> >> thanks to a problem with the dur template function in std.datetime. The
> >> solution used by this pull is to include the function body of the
> >> auto-function as that was needed to allow Phobos to build correctly
> >> using
> >> the DRT DI files. This is the only workable solution as DMD does not
> >> know
> >> the type of an auto-function when DI files are generated. No semantic
> >> analysis has been performed and since semantic analysis could change the
> >> layout of a module you wouldn't want it to be
> >> performed.
> > 
> > Actually, dur is in core.time (which is publicly imported by
> > std.datetime),
> > but regardless, what's wrong with it? It's incredibly straightforward.
> > 
> > - Jonathan M Davis
> 
> All of this is a result of using the above mentioned 928 pull.
> 
> This from core.time.d:
> Duration dur(string units)(long length) @safe pure nothrow
> if(units == "weeks" ||
> units == "days" ||
> units == "hours" ||
> units == "minutes" ||
> units == "seconds" ||
> units == "msecs" ||
> units == "usecs" ||
> units == "hnsecs" ||
> units == "nsecs")
> {
> return Duration(convert!(units, "hnsecs")(length));
> }
> 
> Gets translated to this in core.time.di:
> template dur(string units) if (units == "weeks" || units == "days" ||
> units == "hours" || units == "minutes" || units == "seconds" || units ==
> "msecs" || units == "usecs" || units == "hnsecs" || units == "nsecs")
> {
> pure nothrow @safe Duration dur(long length)
> {
> return Duration(convert!(units,"hnsecs")(length));
> }
> }
> 
> Which results in this error from DMD (HEAD):
> ../druntime/import/core/time.di(218): Error: this cannot be interpreted at
> compile time, because it has no available source code
> std/net/curl.d(187): called from here: dur(2L)
> make[1]: *** [generated/linux/release/32/libphobos2.a] Error 1
> make: *** [release] Error 2
> 
> But DMD, there *IS* source code to read! Even if it is just a function
> call...
> 
> Note the above D->DI translation is the same without the patch, I checked
> on a vanilla DMD 2.059 install. Also, I don't know near enough about
> core.time to begin to guess what D is whining about here... It all looks
> good to me.

Line 187 of std.net.curl is an enum:

private enum _defaultDataTimeout = dur!"minutes"(2);

So, dur!"minutes(2) will be evaluated at compile time. That means that the 
_full_ source of everything that's needed for dur!"minutes"(2) must be 
available. At minimum, that's going to be Duration's source code (including 
the full source for its constructor) and the source of convert.

Duration's constructor is quite straightforward, so as long as its full body 
is included, you should be fine. convert requires the source of hnsecsPer in 
addition to its own source, but hnsecsPer doesn't rely on anything else and 
both of those are templates, so their full source should be in the .di file 
anyway.

So, I would think that as long as the basic declaration for Duration is 
available along with the full source for Duration's constructor, 
std.time.convert, and std.time.hnsecsPer is available, then CTFE should be 
able to evaluate dur!"minutes"(2), and std.curl.net should be fine. So, if any 
of that source is being stripped out, then there's your problem. If it's all 
there, then I don't know what's wrong. Maybe there's another function in 
Duration that got stripped when it was needed (though I don't know what else 
in Duration besides the constructor would be required for dur!"minutes"(2) to 
be evaluated).

Personally, I think that the fact that CTFE requires the full source to work 
is a prime example of why .di files tend to be a very bad idea, but you can 
still strip at least some of it for at least stuff that wouldn't be used in 
CTFE.

- Jonathan M Davis


More information about the Digitalmars-d-announce mailing list