Rethink "source of truth" for Q::Identifier
We know more about identifiers nowadays. This knowledge hasn't really found its way back into the design of Q::Identifier. Maybe it should, and maybe that would make some problems we're currently facing easier to solve.
So. There are two types of identifier:
-
Lexical — these can be represented by a tuple
(n, i)to locate the corresponding declaration, wherenis how manyOUTERpointers we have to follow, andiis an index within the resulting frame. (Note that since blocks are not frames, this lookup has to be performed at runtime in the general case.) -
UniqueDirect — these are represented by aLocation. Identifiers like this happen when a quasi refers to a variable declared in the surrounding macro — after the corresponding code has been injected into the mainline, there's no lexical path that would lead to a lookup of that variable.
Having written #410, I'm more convinced we need to do this anyway to get that semantics/implementation.
Because of the "leapfrogging" example in #410 (you can Ctrl+F for it), I don't think it's a good idea for lexical identifiers to use the (n, i) tuples as their source of truth — because injected code from the quasi can invalidate the n — so probably it's better if lexical variables refer to something unique — either the scope, or the declaration itself.
#372 ties into this, since it wants to tie precedence/associativity information to definition sites. #410 pushes us in the same direction, at compile-time, a variable reference is basically a reference to a definition site, plus a boolean saying whether the reference is unique or not.
The (n, i) tuple we can do, but only after all the macro expansion (and later optimizations) have finished so the references stop moving around in relation to their definitions.