A class named after a used unit is unreachable from outside
Repro
unit widget;
{$MODE PXX}
interface
type TThing = record v: Integer; end;
implementation
end.
unit collide;
{$MODE PXX}
interface
uses widget; { a UNIT called widget ... }
type
Widget = class { ... and a CLASS called Widget. PXX is case-insensitive. }
public
n: Integer;
constructor Create(v: Integer);
end;
implementation
constructor Widget.Create(v: Integer);
begin n := v; end;
end.
program r;
{$MODE PXX}
uses collide;
var a: Widget;
begin
a := Widget.Create(7);
end.
pascal26:6: error: undefined variable (Create)
near: begin a := Widget . Create >>> ( 7 )
Remove uses widget from collide.pas and the identical program compiles and
runs correctly. That is the whole discrimination: the class is fine, the class
name is fine, and the collision with a used unit's name is what breaks it.
Why it matters beyond tidiness
Python module names and our unit names are two namespaces we do not control the
intersection of. lib/rtl/pil.pas must expose Image (Pillow's own spelling)
and must use image (ours). zlib, json, math, random, re and io are
all both Python module names and plausible unit names; any of them growing a
same-named class hits this.
The workaround, and why it is acceptable here
type
TPILImage = class ... end;
Image = TPILImage; { the name callers write }
Verified: construction works, and NilPy still reaches the class through the
alias (m.Widget(7) binds, methods dispatch, fields read back). It costs one
line and a comment. Registered in devdocs/dev/track-b-workarounds.md so it is
deleted when this is fixed rather than becoming folklore.