We need something like source_location in D

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


On Tue, Jul 30, 2019 at 11:29 PM Manu <turkeyman at gmail.com> wrote:
>
> 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));
> }

I refactored my original idea and left it broken... it should be this:

enum getLoc = Loc(__traits(getLocation, symbol));


More information about the Digitalmars-d mailing list