with rec do HelperMember is undefined
{$mode objfpc}
type TC = class v: Integer; end;
TCH = class helper for TC function Two: Integer; end;
function TCH.Two: Integer; begin Result := v * 2; end;
var c: TC;
begin c := TC.Create; c.v := 4; with c do WriteLn(Two); end. { pxx: undefined variable (Two); FPC 8 }
The with scope loop in ParseLValueAST asked the operand's own fields, properties, class vars and methods and never its helpers.
Resolution (2026-09-28)
Each with entry now asks first for a helper of the operand that declares the
name (WithHelperRecFor: ClassHelperRecFor for a class, FindHelperForType on
the record for a record helper), as FPC binds a helper member before the
operand's own. The bare name is handed to the SAME walker x.Name takes,
ParseClassRecordSelectors, entered at the name instead of at a dot
(SelMemberTok, an absolute token index like AtStopDotTok), so Self (by
reference for a record helper), overloads, property accessors and trailing
selectors are the dotted spelling's rather than a copy.
Found with it, both wrong DOTTED too on v445:
- a class-helper PROPERTY was "no such member" (
c.Dbl): ClassHelperRecFor matched only a helper's methods; d.Ownon a TDerived called TBase.Own where FPC calls TBase's helper's Own: ClassHelperRecFor's "the class's own member wins" asked finders that walk the parents, where FPC's rule (stated in its own comment) is "this class declares it". A hit now counts only inside that class's own rows.
Not part of this: a bare field inside a record helper's OWN body (a in
TRH.Sum) is undefined -- franks-a3's record-helper commit fixes it; the rows
here spell Self.a so they stand alone.
Fixtures test/test_with_reaches_a_helper_member{,_delphi}.pas (20 rows each,
.expected generated by FPC 3.2.2): v445 refuses both; this build matches FPC.