Subject: Re: bug#54079: 29.0.50; Method dispatching eratically fails

From: Stefan Monnier <[email-masked]>
Date: Sat, 05 Mar 2022 12:57:09 -0500

> I think this problem can only happen for defuns/defvars/defconts inside
> eval-when-compile or eval-and-compile.
> Would you try out the following patch, please, which I believe fixes the
> bug.

Any chance we could fix it in `bytecomp.el` by calling
`byte_run_strip_symbol_positions` before evaluating the contents of
those forms?

Maybe we should have a function to check for the absence of
sympos which we could call (when in debugging mode only) from
defvar/defalias and friends, which could give us useful backtraces
showing where/when the sympos "leak"?

        Stefan

> diff --git a/src/data.c b/src/data.c
> index 1526cc0c73..0854b4efb4 100644
> --- a/src/data.c
> +++ b/src/data.c
> @@ -942,6 +942,13 @@ The return value is undefined.  */)
>    (register Lisp_Object symbol, Lisp_Object definition, Lisp_Object docstring)
>  {
>    CHECK_SYMBOL (symbol);
> +  /* If we're in a byte compilation, ensure the definition's symbols
> +     are stripped of their positions. */
> +  if (symbols_with_pos_enabled
> +      && SYMBOL_WITH_POS_P (symbol)
> +      && Ffboundp (Qbyte_run_strip_symbol_positions))
> +    call1 (Qbyte_run_strip_symbol_positions, definition);
> +
>    if (!NILP (Vpurify_flag)
>        /* If `definition' is a keymap, immutable (and copying) is wrong.  */
>        && !KEYMAPP (definition))
> @@ -4352,6 +4359,8 @@ This variable cannot be set; trying to do so will signal an error.  */);
>  Bind this to non-nil in applications such as the byte compiler.  */);
>    symbols_with_pos_enabled = false;
>  
> +  DEFSYM (Qbyte_run_strip_symbol_positions, "byte-run-strip-symbol-positions");
> +
>    DEFSYM (Qwatchers, "watchers");
>    DEFSYM (Qmakunbound, "makunbound");
>    DEFSYM (Qunlet, "unlet");
> diff --git a/src/eval.c b/src/eval.c
> index 294d79e67a..1b1fde3a20 100644
> --- a/src/eval.c
> +++ b/src/eval.c
> @@ -794,6 +794,12 @@ usage: (defvar SYMBOL &optional INITVALUE DOCSTRING)  */)
>        if (!NILP (XCDR (tail)) && !NILP (XCDR (XCDR (tail))))
>  	error ("Too many arguments");
>        Lisp_Object exp = XCAR (tail);
> +      /* If we're in a byte compilation, ensure the definition's
> +	 symbols are stripped of their positions. */
> +      if (symbols_with_pos_enabled
> +	  && SYMBOL_WITH_POS_P (sym)
> +	  && Ffboundp (Qbyte_run_strip_symbol_positions))
> +	call1 (Qbyte_run_strip_symbol_positions, exp);
>  
>        tem = Fdefault_boundp (sym);
>        tail = XCDR (tail);
> @@ -861,6 +867,14 @@ usage: (defconst SYMBOL INITVALUE [DOCSTRING])  */)
>      }
>  
>    Finternal__define_uninitialized_variable (sym, docstring);
> +
> +  /* If we're in a byte compilation, ensure the definition's symbols
> +     are stripped of their positions. */
> +  if (symbols_with_pos_enabled
> +      && SYMBOL_WITH_POS_P (sym)
> +      && Ffboundp (Qbyte_run_strip_symbol_positions))
> +    call1 (Qbyte_run_strip_symbol_positions, XCAR (XCDR (args)));
> +
>    tem = eval_sub (XCAR (XCDR (args)));
>    if (!NILP (Vpurify_flag))
>      tem = Fpurecopy (tem);
>
>
>> Michael.