Subject: bug#47552: 27.1; cl-defstruct field names matching read-only variables -> bad code

From: Stefan Monnier <[email-masked]>
Date: Sun, 04 Apr 2021 18:59:36 -0400

>> The issue is related to the generated code for `make-a', which boils
>> down to let binding gcs-done to nil:
>>
>>     (let ((gcs-done)))
>>
>> Eval the above to get the same error.
>>
>> Perhaps the code generated for the make- functions should use
>> make-symbol or gensym instead?  Or a fixed series of field0...fieldN
>> symbols?  Why risk potentially binding dynamic vars?
>
> Using a gensym seems like an obvious solution to me, but perhaps Stefan
> has an opinion here (added to the CCs).

I'm pretty sure that's the right solution, *but* I don't think it's
obvious how to get there: `cl-defstruct` defines the constructor
using `cl-defsubst` and its `&key` arguments, so the `:gcs-gone` keyword
argument inevitably maps to a `gcs-done` variable by definition of how
`&key` is supposed to work.

So I suspect that in order to fix it, we'd need to stop using `&key`, or
to use a more sophisticated version (which I think we'd have to
implement first) which lets you specify separately the keyword and the
matching variable name (and then make sure that the inlining
optimizations still work for it).

        Stefan