Skip to content

1: replace callsite by callTree; 2: NimLineInfo #387

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
timotheecour opened this issue Jun 16, 2021 · 0 comments
Open

1: replace callsite by callTree; 2: NimLineInfo #387

timotheecour opened this issue Jun 16, 2021 · 0 comments

Comments

@timotheecour
Copy link
Member

timotheecour commented Jun 16, 2021

proposals 1,2,3 below (NimLineInfo) can be considered independently from proposal 4 and I could split it in 2 RFCs if needed (only reason i grouped them is there's a common topic regarding callsite). NimLineInfo can in particular be useful to make stacktraces, profile info and instantiation line info forwarding much more compact and efficient (since TLineInfo is small) and allow lazy rendering of line infos.

It also enables generating smaller binaries as explained in nim-lang/Nim#15606 (enforce PR) since things like: proc onEnforceFail[T](typ: typedesc, prefix: string, arg: T) {.noreturn, noinline.} = can now use the much more compact TLineInfo and only render when an exception is thrown, which can be implemented in a more performant way. (see doc comment in lib/std/exceptions.nim from that PR)

proposal 1

  • add a type to represent a raw TLineInfo as used by the compiler (eg: NimLineInfo); unlike LineInfo it doesn't interpret the filename and just faithfully represents it; add macros.nimLineInfo API analog to macros.lineInfoObj to retrieve it from a NimNode

proposal 2

in macros, make proc error(msg: string; n: NimNode = nil) also accept NimLineInfo instead of just n; NimLineInfo can be used when the n is not available
ditto with some other APIs eg warning

proposal 3

add proc callsiteNimLineInfo() which just retrieves the NimLineInfo instead of callsite which retrieves the full NimNode and requires copyTree

proposal 4a (independent of proposal 1, 2, 3)

add callTree which works exactly like the deprecated callsite except it requires the macro where it's called from to be annotated with a new pragma {.callTree.}, otherwise it gives an error

migrate existing calls to callsite to use the new callTree, and turn callsite into an error unless -d:nimLegacyCallsite is used; when -d:nimLegacyCallsite is not used, we can now avoid the expensive calls to copyTree in all places except ones that use {.callTree.}

proposal 4b (alternative to proposal 4a)

support this:

macro fn(a: int, n = callTree)

where callTree is expanded in caller and would in effect be equivalent to calling n = callsite() inside fn. This would be analog to C, C++ or D's __FILE__, __LINE__ and __FUNCTION__ + friends, except, of course, better.

This would address IMO the concern of scope violation.
The tricky part here regards varargs handling and how to avoid ambiguity in this case, but I think it's solvable by requiring it to be passed by keyword, ie:

macro echo2(args: varargs[untyped], n = callTree) = ...
echo2(1, 2, 3) # instatiates n = callTree at caller site
echo2(1, 2, 3, n = n2) # forwarding callTree from somewhere else (eg parent)


macro echo3(a: int, body: untyped, n = callTree) = ...
echo3(1): # n = callTree at caller site
  stmt1
  stmt2

echo3(1, do:
  smt1
  smt2, n = n2)

note

callsite has real uses so outright removing it is not good, however the proposed callTree should address all concerns, in particular avoiding copyTree on each call except the few that are enabled via {.callTree.}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant