bug: argument lists accept empty slots and build a zero-width ARG node #2
Labels
No labels
accessibility
bug
documentation
duplicate
enhancement
good first issue
help wanted
invalid
question
wontfix
No milestone
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
barrettruth/starlark-cst#2
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Version
0.1.1
Dialect
Dialect::Bazel, reproduced onBUILDand.bzl. Not dialect-specific.Which guarantee broke
Wrong tree shape, plus a missing error. Round-trip holds and nothing panics.
Observed
An empty slot in an argument list is accepted silently and produces a
zero-width
ARGnode:foo(, a)andfoo(,)are likewise accepted with zero errors.Why this is a bug and not a tolerated recovery
Lists and dicts already reject the same construct, so this is an argument-list
oversight rather than a deliberate policy:
x = [1, , 2]x = {1: 2, , 3: 4}foo(a, , b)foo(, a)foo(,)A zero-width
ARGis also not a well-formed node. Every otherARGin thetree spans its expression; consumers that walk
ARG_LIST—CallExpr::arg,anything counting positional arguments, anything mapping a cursor offset to an
argument — get a node with no content and no position to report. In a
BUILDfile that is
cc_library(name = "a", , srcs = [...])silently presenting anextra argument.
Precedent
Both reference implementations reject it, at the comma:
Note the anchor is the offending comma, and it is one character wide.
Bazel's own grammar permits a trailing comma before
)and nothing else;Parser.javacarriesTrailing comma is allowed only in parenthesized tuples.for the adjacent case, so the distinction between trailing and empty slot
is one it draws explicitly.
Proposed behaviour
Reject an empty argument slot with the same message the parser already uses
elsewhere for a missing operand, anchored on the comma that opens the empty
slot and one character wide:
foo(a, , b)expected an expression,,7..8foo(, a)expected an expression,,4..5foo(,)expected an expression,,4..5foo(a,)must stay accepted — a single trailing comma before)is legal.The zero-width
ARGnode should not be produced. Either omit the node and letthe
COMMAtokens sit directly inARG_LIST, or wrap the comma in anERRORnode, whichever matches how the list and dict paths already recover. Both keep
round-trip intact.
Minimal reproduction
Fixed by
48aa58d.