← board

A set parameter lost its element kind, so for x in p refused it

What it looked like

type TM = (mA, mB, mC); TMs = set of TM;
procedure P(const q: TMs); var m: TM; begin for m in q do Write(Ord(m)); end;

error: for-in: set iteration supports set of <enum>, set of Char or an ordinal set constructor — for a parameter that is precisely set of <enum>.

The message was not wrong about its own inputs. BuildForInSetLoop reaches its else Error(...) when the symbol carries neither an enum id nor an element kind, and that is what a parameter carried. It described the value stack faithfully and said nothing about the program, which is the same shape as the comparison requires integer operands note in paslexer.inc.

The boundary, which is what identified the cause

shape before
local, anonymous set of TM works
local, named TMs works
value / const / var param, named or anonymous all refused
set of Char param, set of Byte param refused
set as a record FIELD works

Locals and record fields both worked, which ruled out the type alias and the element kinds and left exactly one thing in common: the parameter symbol. So this was never the alias-identity family it first resembled ([[bug-p-a-type-alias-drops-the-enum-identity-and-a-set-drops-its-char-element-kind]]); varying the shape before touching anything is what separated them.

Why only one of four columns had been captured

ptypesSetEnum exists and is captured correctly — its window discipline was already right. It just goes somewhere else: ProcParamSetEnumId, the argument-check column the CALLER reads. Nothing wrote the callee-side symbol. And because only the enum id was staged, set of Char and set of 1..9 had no representation at all even if someone had stamped it — hence four columns, not one.

Same family as the four notes already in that file (ptypesStrCap, ptypesFileRecSize, ptypesStrElemTk, ptypesEnum), all of which exist because the allocation loop runs after every parameter's type is parsed and therefore reads the LAST one. test_set_param_for_in.pas's 2nd of 3 row is the control for exactly that.

Two notes on the tests

Left open, deliberately

[[bug-p-for-in-over-a-set-returning-function-call-is-refused]] — found in the same pass, a different mechanism (the container dispatch, not the element-kind test), and this fix did not move it. Filed rather than folded in.