Subject: bug#65017: 29.1; Byte compiler interaction with cl-lib function objects, removes symbol-function

From: Stefan Monnier <[email-masked]>
Date: Thu, 03 Aug 2023 17:00:53 -0400

>> That's a side problem.  If absolutely needed, we could add some ad-hoc
>> invalidation to work around the core problem, but I'd rather fix the
>> core problem.
>
> Are you sure?

Yes.

> What is the core problem?

The core problem is that we want to stop infinite macroexpansion of the
same term.  I.e. we want to stop macroexpansion from turning

    (function FOO)
=>
    (function FOO)
=>
    (function FOO)
=>
    ...

so we tweak the macro-expander for `function` so that if FOO is exaction
the same as last time, we return the exact list (function FOO) we built
last time, rather than building a new one.

If `eq` works as god intended (i.e. it performs a pointer-equality
test), then this is perfectly safe because the cache always has the form

    (#1=<SYM> . (function #1#))

so using the `cdr` of the cache returns something perfectly equivalent
to `(function ,f) just with the added twist that it's the exact same
list we return last time so may stop the macroexpansion.  So it's safe
the use the cache even when it's stale.

But with `symbols-with-pos-enabled` the `eq` test can end up using the
cache when FOO is not 100% the same as <SYM> and so we can end up
replacing `equal` or #<symbol equal at 467> with (function #<symbol
equal at 81>) neither of which is really correct, the second of which
can happen even if we try and flush the cache.

> As I see it, if the function cl--labels-convert is called during byte
> compilation, cl--labels-convert-cache is going to get symbols with
> position.  This is expected and is what we want - such a symbol might
> easily give the position element of an error occurring in expanded code.

Exactly, which is why the `eq` needs to pay attention to the
position information.

> So why would it not be a complete bug fix to initialise this variable
> to nil at the start of every cl-flet or cl-labels?

Because it could/would still replace some sympos with others within the
same `cl-label`.

        Stefan