Skip to content

parser: report the depth cap at a token index, like every other error - #45

Merged
VeaaC merged 1 commit into
mainfrom
too-deep-offset-2.22
Aug 14, 2026
Merged

parser: report the depth cap at a token index, like every other error#45
VeaaC merged 1 commit into
mainfrom
too-deep-offset-2.22

Conversation

@VeaaC

@VeaaC VeaaC commented Aug 14, 2026

Copy link
Copy Markdown
Owner

A parser reports a failure position RELATIVE to the range it was given, and for the token parser that position is a token index -- the resolver maps it back to file:line:col on the way out. too_deep() stored in.front().byte_offset instead, so a byte count landed in the slot the resolver reads as a token index.

Both shapes ran off the end of the file: 60 nested messages in a 121-line file reported 122:1, and an option value with 51 nested '[' reported 3:1 for a bracket on line 2. The rejection itself was always correct; only its position was wrong.

The fix is 0, not a computed index: every caller checks the depth BEFORE consuming anything, so the offending token is its range's first, and the sequential combinators lift the offset as it propagates. That makes the input parameter unnecessary.

The tests assert the rendered diagnostic, since the position is the whole point. The first pins no line number -- it cannot see the cap and should not encode it -- and instead requires two files of DIFFERENT depth to report the same line, which is what a byte offset or a mis-lifted index breaks, plus that the line is inside the file and opens a message. The second pins column 62 exactly: "option x = " is 11 characters, so the 51st bracket -- the first one over the cap of 50 -- sits there.

A parser reports a failure position RELATIVE to the range it was given, and for the
token parser that position is a token index -- the resolver maps it back to
file:line:col on the way out. too_deep() stored `in.front().byte_offset` instead, so
a byte count landed in the slot the resolver reads as a token index.

Both shapes ran off the end of the file: 60 nested messages in a 121-line file
reported 122:1, and an option value with 51 nested '[' reported 3:1 for a bracket on
line 2. The rejection itself was always correct; only its position was wrong.

The fix is 0, not a computed index: every caller checks the depth BEFORE consuming
anything, so the offending token is its range's first, and the sequential combinators
lift the offset as it propagates. That makes the input parameter unnecessary.

The tests assert the rendered diagnostic, since the position is the whole point. The
first pins no line number -- it cannot see the cap and should not encode it -- and
instead requires two files of DIFFERENT depth to report the same line, which is what
a byte offset or a mis-lifted index breaks, plus that the line is inside the file and
opens a message. The second pins column 62 exactly: "option x = " is 11 characters,
so the 51st bracket -- the first one over the cap of 50 -- sits there.
@VeaaC
VeaaC merged commit 8e0bf68 into main Aug 14, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant