We need something like source_location in D

Manu turkeyman at gmail.com
Wed Jul 31 06:29:17 UTC 2019


On Tue, Jul 30, 2019 at 8:55 PM Nicholas Wilson via Digitalmars-d
<digitalmars-d at puremagic.com> wrote:
>
> On Wednesday, 31 July 2019 at 01:39:05 UTC, Andrej Mitrovic wrote:
> > From C++20:
> > http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1208r5.pdf
> >
> > Instead of having to constantly declare "file = __FILE__, line
> > = __LINE__" everywhere, it would be so much more useful to just
> > have a single built-in type which we can default initialize .
> > For example:
> >
> > -----
> > import std.algorithm;
> >
> > void checkAndThrow (lazy bool expression, Loc loc =
> > __LOCATION__)
> > {
> >     if (!expression)
> >         throw new Exception("Failed", loc.file, loc.line);
> > }
> >
> > void main ()
> > {
> >     auto arr = [1, 1, 1, 1];
> >     checkAndThrow(arr.sum == 4);
> >
> >     // should throw with file+line of this statement
> >     checkAndThrow(arr.sum == 5);
> > }
> > -----
> >
> > This also makes it very easy to extend in the future, because
> > we don't have to pollute the namespace with a lot of "__"-style
> > symbols.
> >
> > The actual naming of the location symbol is something we can
> > bikeshed over, that's fine.
> >
> > If you grep for `string file = __FILE__, size_t line =
> > __LINE__` or `string file = __FILE__, int line = __LINE__`, it
> > is everywhere in Druntime and Phobos. I think it's time we got
> > rid of this repetition.
> >
> > I know __traits(getLocation) got implemented recently, but it's
> > not very useful in this context because it returns a tuple
> > (https://github.com/dlang/dmd/pull/10013). I don't see an easy
> > way to use it in function parameters.
>
> It returning a tuple is not the problem because they auto expand :
>
> void foo(string a, int b, int c)
> {
>      import std.stdio;
>      writeln(a, " ", b);
> }
> void main()
> {
>      foo(__traits(getLocation,foo));
> }
>
> That you can't pass the caller loc is.
>
> A DIP will take a long time, I don't think the addition of
> __SYMBOLS__ require one. The addition of a type will possibly be
> problematic, but if  `Loc` were a tuple that would be fine if we
> could do
>
> void foo(auto a = 1);
>
> since it would be just as silly to have to type
>
> void foo(typeof(__LOCATION__) loc =  __LOCATION__);

Make a `Loc` type in the library:

struct Loc
{
  string file;
  int line;
  int column;
}

Make a helper to construct one:

template getLoc(alias symbol)
{
  enum getLoc = return Loc(__traits(getLocation, symbol));
}

Do:

Loc loc = getLoc!mySymbol;

Trivial.


More information about the Digitalmars-d mailing list