← board

A const and a routine of one name silently resolve to the const

The trail, because none of it started here

examples/tk/uses_tkinter_and_configparser was the one example failing on every cross target. Its i386 cause read:

pascal26:5563: error: target i386: symbol kind not supported yet (load)
  in: ./compiler/builtin/pyeval.pas

which names nothing. The branch one if BELOW it in the same procedure already knew to name the symbol, and carries a note saying why: "the reported line belongs to the UNIT being parsed rather than to the file you invoked, so there is nothing to grep for." That fix had been made once and this branch was left out. Naming it took one edit and turned the message into:

target i386: symbol 'PYITER_MAP' is a CONST symbol in load position

...at Result := pyiter_map(key, v);.

The defect

pylib.pas:103 declares PYITER_MAP = 4, a TPyIter.FKind tag. pylib.pas:1423 declares function pyiter_map(key: Pointer; const v: Variant). Pascal is case-insensitive: those are the same identifier. Four of the tags collided with their own constructors — pyiter_map, pyiter_filter, pyiter_zip, pyiter_enum.

pxx resolved the call to the CONST, folded it to a literal, and dropped the argument list. Minimal form:

const MY_THING = 4;
function my_thing(a: Integer): Integer;
begin my_thing := a * 100; end;
...
r := my_thing(7);        { was: 4 }

Every target. x86-64 built it happily; only i386 refuses to load a const symbol and so was the only one that said anything, about something else.

FPC rejects the declaration pair outright — "overloaded identifier MY_THING isn't a function" — so no parity check could have found this.

Fixed at both ends, because one of them is not enough

The library. The whole PYITER_* tag family is renamed PYITER_K_* (13 constants, 59 occurrences, confined to pylib.pas). The prefix rather than four renames, because the trap is STRUCTURAL: any kind added later whose name matches its constructor's walks into it again, and the failure is a plausible small integer. The rule is written where the family is declared.

The compiler. A const followed by an argument list is now a refusal naming which way the identifier resolved and what to do. We keep ACCEPTING the declaration pair — a tag constant beside its constructor is a real thing to write, and accepting what FPC rejects is not a defect — but a call of the const is a mistake under any reading, and the rule is to leave the mistake visible rather than to answer it.

Verification

What it says about the shape

Third silent-wrong-answer in this session whose only witness was a REFUSAL on a minority backend: the by-value record, the Write-method arity, and this. The x86-64 path has the fewest guards because it is the one everything is developed on, which is exactly backwards. A refusal on a cross target is worth reading before it is worth ranking.