@@ -161,16 +161,18 @@ binder, label, constructor, type-name, or qualified-identifier positions infer
161161` id` . For example, in `for $counter = 0; $counter < $limit; ...`, `$counter`
162162infers `id` from the binder position and `$limit` infers `exp`.
163163
164- Only `exp`, `id`, `const`, and `pat` are supported. A name may be repeated
164+ Only `exp`, `id`, `const`, `arg`, and `pat` are supported. A name may be repeated
165165within one kind, but using the same payload across multiple kinds such as
166- ` $(name:exp)` , `$(name:id)`, `$(name:const)`, and `$(name:pat)` in one shape is
167- invalid.
166+ ` $(name:exp)` , `$(name:id)`, `$(name:const)`, `$(name:arg)`, and
167+ ` $(name:pat) ` in one shape is invalid.
168168
169169Bare `$name` inference is intentionally conservative. It does not default to
170- ` const` or `pat`. A simple pattern variable such as `match input { $item => body
171- }` is ambiguous between `id`, `const`, and `pat`; write `$(item:id)`,
172- ` $(item:const)` , or `$(item:pat)` to choose. An explicit same-name occurrence
173- also fixes later bare occurrences when the positions are compatible.
170+ ` const` , `arg`, or `pat`. A simple pattern variable such as
171+ ` match input { $item => body }` is ambiguous between `id`, `const`, and `pat`;
172+ write `$(item:id)`, `$(item:const)`, or `$(item:pat)` to choose. Bare `$name`
173+ does not infer `arg`; use explicit `$(name:arg)` for whole call arguments. An
174+ explicit same-name occurrence also fixes later bare occurrences when the
175+ positions are compatible.
174176
175177The old YAML `metavars` key is not supported. Pattern objects that contain it
176178are rejected as using an unsupported key.
@@ -214,6 +216,19 @@ Use `$(name:const)` for literal constants. It is valid only as a whole bare
214216identifier expression or as a simple pattern variable position, and it matches
215217only parsed MoonBit constants.
216218
219+ Use `$(name:arg)` for a whole function-call argument slot. It is valid only as
220+ an entire bare positional argument in a call pattern :
221+
222+ ` ` ` yaml
223+ patterns:
224+ - shape: sink($(arg:arg))
225+ ` ` `
226+
227+ The placeholder can match a candidate positional argument, labelled argument,
228+ labelled pun, optional labelled argument, or optional labelled pun. The captured
229+ value is the whole `Argument` AST node, including argument kind, label, and
230+ value.
231+
217232Use `$(name:pat)` for a whole pattern AST capture. It is valid only as a simple
218233pattern variable position :
219234
@@ -355,6 +370,41 @@ patterns:
355370 - shape: match input { $(lit:const) => lit }
356371` ` `
357372
373+ # ## `arg`
374+
375+ An `arg` metavar captures a complete call argument node. It is useful when a
376+ rule should accept any argument spelling in one slot while still comparing the
377+ entire slot on repeated occurrences.
378+
379+ Example :
380+
381+ ` ` ` yaml
382+ patterns:
383+ - shape: sink($(arg:arg))
384+ ` ` `
385+
386+ This can match all of these one-argument calls :
387+
388+ ` ` ` moonbit
389+ sink(value)
390+ sink(label=value)
391+ sink(label~)
392+ sink(label?=value)
393+ sink(label?)
394+ ` ` `
395+
396+ Repeating the same `arg` name requires the full argument nodes to be
397+ structurally equal, ignoring source locations. Argument kind, label, and value
398+ must all match. The pattern `sink($(arg:arg), $(arg:arg))` can match
399+ ` sink(value, value)` and `sink(label=value, label=value)`, but not
400+ ` sink(value, other)` or `sink(label=value, other=value)`.
401+
402+ ` arg` is explicit-only. Bare `$arg` in `sink($arg)` still follows normal bare
403+ metavar inference and is an `exp` capture unless the name was explicitly
404+ declared as another kind elsewhere. `$(arg:arg)` must occupy the whole
405+ argument slot; `sink(label=$(arg:arg))`, `sink($(arg:arg) + 1)`, and a root
406+ shape `$(arg:arg)` are invalid.
407+
358408# ## `pat`
359409
360410A `pat` metavar captures the whole candidate `Pattern` AST. It is valid only in
@@ -387,9 +437,9 @@ patterns:
387437` ` `
388438
389439Only `id` and `const` captures can be guarded. A guard key that refers to an
390- ` exp` capture, a `pat` capture, or an unknown name is rejected during rule
391- compilation. Inner `patterns` may guard `id` and `const` captures established by
392- ` inside-expr` .
440+ ` exp` capture, an `arg` capture, a `pat` capture, or an unknown name is
441+ rejected during rule compilation. Inner `patterns` may guard `id` and `const`
442+ captures established by `inside-expr`.
393443
394444Guards are checked after the structural AST match succeeds. All guards in a
395445single pattern object must match; this is AND semantics. Regex matching uses
@@ -686,8 +736,9 @@ A rule set or rule file is rejected when any of these conditions occurs:
686736- an metavar uses a reserved name
687737- ` $(name:exp)` appears outside a bare expression position
688738- ` $(name:const)` appears outside a constant expression or constant pattern position
739+ - ` $(name:arg)` appears outside a bare argument position
689740- ` $(name:pat)` appears outside a bare pattern position
690- - a guard key is not `$`-prefixed, or references an unknown, `exp`, or `pat` capture
741+ - a guard key is not `$`-prefixed, or references an unknown, `exp`, `arg`, or `pat` capture
691742- a guard regex is invalid
692743- ` inside-expr` does not contain exactly one binding-capable `__TARGET__`
693744- a structural `patterns` or `patterns-not` entry contains binding-capable
0 commit comments