← board

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.