Thanks to visit codestin.com
Credit goes to github.com

Skip to content

feat(candid_parser)!: parse and preserve named function arguments#742

Merged
lwshang merged 3 commits into
masterfrom
js-bindgen-named-args-parser
Jun 23, 2026
Merged

feat(candid_parser)!: parse and preserve named function arguments#742
lwshang merged 3 commits into
masterfrom
js-bindgen-named-args-parser

Conversation

@lwshang

@lwshang lwshang commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Summary

Lets binding generators emit meaningful parameter names (transfer(to, amount) instead of transfer(arg0, arg1)) by capturing argument/result names in the candid_parser AST — without changing the candid type model (candid stays 0.10).

This is the subset of the next branch's named-args feature that the icp-js-bindgen project needs, ported to master so it can depend on published releases instead of the floating next branch.

Changes

candid_parser — breaking (0.3.2 → 0.4.0)

  • New syntax::IDLArgType { typ: IDLType, name: Option<String> } with IDLArgType::new / new_with_name (purely numeric names normalize to None).
  • FuncType::{args, rets}, IDLType::ClassT, IDLTypes::args, and IDLInitArgs::args now hold Vec<IDLArgType> instead of Vec<IDLType>.
  • Grammar captures named args (with a uniqueness check); the pretty-printer round-trips them (e.g. (from : principal)).
  • Type checking is unchanged — names are dropped when lowering to candid::types::Function, so the candid crate's type model is unaffected.

candid — non-breaking (0.10.29 → 0.10.30)

  • Add pretty::utils::sep_enclose / sep_enclose_space (list/tuple combinators).
  • Add TypeEnv::to_sorted_iter() for deterministic, key-sorted iteration.

Test plan

  • cargo test --workspace --all-features (golden .did files updated to reflect preserved arg names)
  • cargo clippy -p candid_parser --all-features
  • Verified the consuming icp-js-bindgen crate builds against these changes (host + wasm32-unknown-unknown)

🤖 Generated with Claude Code

lwshang and others added 2 commits June 23, 2026 09:54
Capture argument and result names in the parser AST so binding generators
(e.g. the JS bindgen) can emit meaningful parameter names instead of
positional `arg0`/`arg1`.

candid_parser (breaking, 0.3.2 -> 0.4.0):
- Add `syntax::IDLArgType { typ: IDLType, name: Option<String> }` with
  `new`/`new_with_name` (purely numeric names normalize to `None`).
- `FuncType::{args,rets}`, `IDLType::ClassT`, `IDLTypes::args`, and
  `IDLInitArgs::args` now hold `Vec<IDLArgType>` instead of `Vec<IDLType>`.
- Grammar captures named args; the pretty-printer round-trips names.
- Type checking is unchanged: names are dropped when lowering to
  `candid::types::Function`, so the candid type model is unaffected.

candid (non-breaking, 0.10.29 -> 0.10.30):
- Add `pretty::utils::sep_enclose` / `sep_enclose_space`.
- Add `TypeEnv::to_sorted_iter()`.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
@github-actions

github-actions Bot commented Jun 23, 2026

Copy link
Copy Markdown
Name Max Mem (Kb) Encode Decode
blob 4_224 4_207_449 2_121_397
btreemap 75_456 529_878_266 ($\textcolor{red}{0.00\%}$) 10_166_634_693
double_option 128 1_322_452 ($\textcolor{red}{0.07\%}$) 27_197_905
large_variant 320 1_038_185 ($\textcolor{red}{0.09\%}$) 20_327_052
multi_arg 64 551_522 6_282_711
nns 192 1_992_456 ($\textcolor{red}{0.00\%}$) 5_507_178 ($\textcolor{green}{-0.04\%}$)
nns_list_neurons 1_152 6_591_925 ($\textcolor{green}{-0.02\%}$) 210_714_588 ($\textcolor{red}{0.00\%}$)
nns_list_proposal 1_216 6_907_923 ($\textcolor{green}{-0.11\%}$) 55_061_919 ($\textcolor{green}{-0.00\%}$)
option_list 128 727_821 ($\textcolor{red}{0.00\%}$) 16_423_653
result_variant 192 1_378_318 ($\textcolor{green}{-0.03\%}$) 16_140_430
subtype_decode 512 2_664_845 ($\textcolor{red}{0.03\%}$) 49_364_518 ($\textcolor{red}{0.00\%}$)
text 6_336 4_204_305 7_877_258
variant_list 128 722_331 ($\textcolor{red}{0.00\%}$) 15_625_423
vec_int16 12_480 8_404_571 249_585_709
vec_nat 11_008 66_046_846 276_028_297
vec_nat32 24_768 16_793_179 243_294_534
vec_nat64 49_344 33_570_379 251_683_396
vec_service 64 687_601 ($\textcolor{green}{-0.17\%}$) 94_832_635
wide_record 1_152 3_267_512 ($\textcolor{red}{0.01\%}$) 44_558_104 ($\textcolor{red}{0.00\%}$)
  • Parser cost: 15_594_000 ($\textcolor{red}{0.04\%}$)
  • Extra args: 2_861_924
Click to see raw report
---------------------------------------------------

Benchmark: blob
  total:
    instructions: 6.33 M (no change)
    heap_increase: 66 pages (no change)
    stable_memory_increase: 0 pages (no change)

  1. Encoding (scope):
    calls: 1 (no change)
    instructions: 4.21 M (no change)
    heap_increase: 66 pages (no change)
    stable_memory_increase: 0 pages (no change)

  2. Decoding (scope):
    calls: 1 (no change)
    instructions: 2.12 M (no change)
    heap_increase: 0 pages (no change)
    stable_memory_increase: 0 pages (no change)

---------------------------------------------------

Benchmark: btreemap
  total:
    instructions: 10.70 B (0.00%) (change within noise threshold)
    heap_increase: 1179 pages (no change)
    stable_memory_increase: 0 pages (no change)

  1. Encoding (scope):
    calls: 1 (no change)
    instructions: 529.88 M (0.00%) (change within noise threshold)
    heap_increase: 159 pages (no change)
    stable_memory_increase: 0 pages (no change)

  2. Decoding (scope):
    calls: 1 (no change)
    instructions: 10.17 B (no change)
    heap_increase: 1020 pages (no change)
    stable_memory_increase: 0 pages (no change)

---------------------------------------------------

Benchmark: double_option
  total:
    instructions: 28.52 M (0.00%) (change within noise threshold)
    heap_increase: 2 pages (no change)
    stable_memory_increase: 0 pages (no change)

  1. Encoding (scope):
    calls: 1 (no change)
    instructions: 1.32 M (0.07%) (change within noise threshold)
    heap_increase: 0 pages (no change)
    stable_memory_increase: 0 pages (no change)

  2. Decoding (scope):
    calls: 1 (no change)
    instructions: 27.20 M (no change)
    heap_increase: 2 pages (no change)
    stable_memory_increase: 0 pages (no change)

---------------------------------------------------

Benchmark: extra_args
  total:
    instructions: 2.86 M (no change)
    heap_increase: 0 pages (no change)
    stable_memory_increase: 0 pages (no change)

---------------------------------------------------

Benchmark: large_variant
  total:
    instructions: 21.37 M (0.00%) (change within noise threshold)
    heap_increase: 5 pages (no change)
    stable_memory_increase: 0 pages (no change)

  1. Encoding (scope):
    calls: 1 (no change)
    instructions: 1.04 M (0.09%) (change within noise threshold)
    heap_increase: 2 pages (no change)
    stable_memory_increase: 0 pages (no change)

  2. Decoding (scope):
    calls: 1 (no change)
    instructions: 20.33 M (no change)
    heap_increase: 3 pages (no change)
    stable_memory_increase: 0 pages (no change)

---------------------------------------------------

Benchmark: multi_arg
  total:
    instructions: 6.84 M (no change)
    heap_increase: 1 pages (no change)
    stable_memory_increase: 0 pages (no change)

  1. Encoding (scope):
    calls: 1 (no change)
    instructions: 551.52 K (no change)
    heap_increase: 1 pages (no change)
    stable_memory_increase: 0 pages (no change)

  2. Decoding (scope):
    calls: 1 (no change)
    instructions: 6.28 M (no change)
    heap_increase: 0 pages (no change)
    stable_memory_increase: 0 pages (no change)

---------------------------------------------------

Benchmark: nns
  total:
    instructions: 23.93 M (0.02%) (change within noise threshold)
    heap_increase: 3 pages (no change)
    stable_memory_increase: 0 pages (no change)

  0. Parsing (scope):
    calls: 1 (no change)
    instructions: 15.59 M (0.04%) (change within noise threshold)
    heap_increase: 3 pages (no change)
    stable_memory_increase: 0 pages (no change)

  1. Encoding (scope):
    calls: 1 (no change)
    instructions: 1.99 M (0.00%) (change within noise threshold)
    heap_increase: 0 pages (no change)
    stable_memory_increase: 0 pages (no change)

  2. Decoding (scope):
    calls: 1 (no change)
    instructions: 5.51 M (-0.04%) (change within noise threshold)
    heap_increase: 0 pages (no change)
    stable_memory_increase: 0 pages (no change)

---------------------------------------------------

Benchmark: nns_list_neurons
  total:
    instructions: 217.31 M (-0.00%) (change within noise threshold)
    heap_increase: 18 pages (no change)
    stable_memory_increase: 0 pages (no change)

  1. Encoding (scope):
    calls: 1 (no change)
    instructions: 6.59 M (-0.02%) (change within noise threshold)
    heap_increase: 18 pages (no change)
    stable_memory_increase: 0 pages (no change)

  2. Decoding (scope):
    calls: 1 (no change)
    instructions: 210.71 M (0.00%) (change within noise threshold)
    heap_increase: 0 pages (no change)
    stable_memory_increase: 0 pages (no change)

---------------------------------------------------

Benchmark: nns_list_proposal
  total:
    instructions: 61.97 M (-0.01%) (change within noise threshold)
    heap_increase: 19 pages (no change)
    stable_memory_increase: 0 pages (no change)

  1. Encoding (scope):
    calls: 1 (no change)
    instructions: 6.91 M (-0.11%) (change within noise threshold)
    heap_increase: 5 pages (no change)
    stable_memory_increase: 0 pages (no change)

  2. Decoding (scope):
    calls: 1 (no change)
    instructions: 55.06 M (-0.00%) (change within noise threshold)
    heap_increase: 14 pages (no change)
    stable_memory_increase: 0 pages (no change)

---------------------------------------------------

Benchmark: option_list
  total:
    instructions: 17.15 M (0.00%) (change within noise threshold)
    heap_increase: 2 pages (no change)
    stable_memory_increase: 0 pages (no change)

  1. Encoding (scope):
    calls: 1 (no change)
    instructions: 727.82 K (0.00%) (change within noise threshold)
    heap_increase: 0 pages (no change)
    stable_memory_increase: 0 pages (no change)

  2. Decoding (scope):
    calls: 1 (no change)
    instructions: 16.42 M (no change)
    heap_increase: 2 pages (no change)
    stable_memory_increase: 0 pages (no change)

---------------------------------------------------

Benchmark: result_variant
  total:
    instructions: 17.52 M (-0.00%) (change within noise threshold)
    heap_increase: 3 pages (no change)
    stable_memory_increase: 0 pages (no change)

  1. Encoding (scope):
    calls: 1 (no change)
    instructions: 1.38 M (-0.03%) (change within noise threshold)
    heap_increase: 1 pages (no change)
    stable_memory_increase: 0 pages (no change)

  2. Decoding (scope):
    calls: 1 (no change)
    instructions: 16.14 M (no change)
    heap_increase: 2 pages (no change)
    stable_memory_increase: 0 pages (no change)

---------------------------------------------------

Benchmark: subtype_decode
  total:
    instructions: 52.03 M (0.00%) (change within noise threshold)
    heap_increase: 8 pages (no change)
    stable_memory_increase: 0 pages (no change)

  1. Encoding (scope):
    calls: 1 (no change)
    instructions: 2.66 M (0.03%) (change within noise threshold)
    heap_increase: 8 pages (no change)
    stable_memory_increase: 0 pages (no change)

  2. Decoding (scope):
    calls: 1 (no change)
    instructions: 49.36 M (0.00%) (change within noise threshold)
    heap_increase: 0 pages (no change)
    stable_memory_increase: 0 pages (no change)

---------------------------------------------------

Benchmark: text
  total:
    instructions: 12.08 M (no change)
    heap_increase: 99 pages (no change)
    stable_memory_increase: 0 pages (no change)

  1. Encoding (scope):
    calls: 1 (no change)
    instructions: 4.20 M (no change)
    heap_increase: 66 pages (no change)
    stable_memory_increase: 0 pages (no change)

  2. Decoding (scope):
    calls: 1 (no change)
    instructions: 7.88 M (no change)
    heap_increase: 33 pages (no change)
    stable_memory_increase: 0 pages (no change)

---------------------------------------------------

Benchmark: variant_list
  total:
    instructions: 16.35 M (0.00%) (change within noise threshold)
    heap_increase: 2 pages (no change)
    stable_memory_increase: 0 pages (no change)

  1. Encoding (scope):
    calls: 1 (no change)
    instructions: 722.33 K (0.00%) (change within noise threshold)
    heap_increase: 0 pages (no change)
    stable_memory_increase: 0 pages (no change)

  2. Decoding (scope):
    calls: 1 (no change)
    instructions: 15.63 M (no change)
    heap_increase: 2 pages (no change)
    stable_memory_increase: 0 pages (no change)

---------------------------------------------------

Benchmark: vec_int16
  total:
    instructions: 257.99 M (no change)
    heap_increase: 195 pages (no change)
    stable_memory_increase: 0 pages (no change)

  1. Encoding (scope):
    calls: 1 (no change)
    instructions: 8.40 M (no change)
    heap_increase: 130 pages (no change)
    stable_memory_increase: 0 pages (no change)

  2. Decoding (scope):
    calls: 1 (no change)
    instructions: 249.59 M (no change)
    heap_increase: 65 pages (no change)
    stable_memory_increase: 0 pages (no change)

---------------------------------------------------

Benchmark: vec_nat
  total:
    instructions: 342.08 M (no change)
    heap_increase: 172 pages (no change)
    stable_memory_increase: 0 pages (no change)

  1. Encoding (scope):
    calls: 1 (no change)
    instructions: 66.05 M (no change)
    heap_increase: 33 pages (no change)
    stable_memory_increase: 0 pages (no change)

  2. Decoding (scope):
    calls: 1 (no change)
    instructions: 276.03 M (no change)
    heap_increase: 139 pages (no change)
    stable_memory_increase: 0 pages (no change)

---------------------------------------------------

Benchmark: vec_nat32
  total:
    instructions: 260.09 M (no change)
    heap_increase: 387 pages (no change)
    stable_memory_increase: 0 pages (no change)

  1. Encoding (scope):
    calls: 1 (no change)
    instructions: 16.79 M (no change)
    heap_increase: 258 pages (no change)
    stable_memory_increase: 0 pages (no change)

  2. Decoding (scope):
    calls: 1 (no change)
    instructions: 243.29 M (no change)
    heap_increase: 129 pages (no change)
    stable_memory_increase: 0 pages (no change)

---------------------------------------------------

Benchmark: vec_nat64
  total:
    instructions: 285.26 M (no change)
    heap_increase: 771 pages (no change)
    stable_memory_increase: 0 pages (no change)

  1. Encoding (scope):
    calls: 1 (no change)
    instructions: 33.57 M (no change)
    heap_increase: 514 pages (no change)
    stable_memory_increase: 0 pages (no change)

  2. Decoding (scope):
    calls: 1 (no change)
    instructions: 251.68 M (no change)
    heap_increase: 257 pages (no change)
    stable_memory_increase: 0 pages (no change)

---------------------------------------------------

Benchmark: vec_service
  total:
    instructions: 95.52 M (-0.00%) (change within noise threshold)
    heap_increase: 1 pages (no change)
    stable_memory_increase: 0 pages (no change)

  1. Encoding (scope):
    calls: 1 (no change)
    instructions: 687.60 K (-0.17%) (change within noise threshold)
    heap_increase: 0 pages (no change)
    stable_memory_increase: 0 pages (no change)

  2. Decoding (scope):
    calls: 1 (no change)
    instructions: 94.83 M (no change)
    heap_increase: 1 pages (no change)
    stable_memory_increase: 0 pages (no change)

---------------------------------------------------

Benchmark: wide_record
  total:
    instructions: 47.83 M (0.00%) (change within noise threshold)
    heap_increase: 18 pages (no change)
    stable_memory_increase: 0 pages (no change)

  1. Encoding (scope):
    calls: 1 (no change)
    instructions: 3.27 M (0.01%) (change within noise threshold)
    heap_increase: 18 pages (no change)
    stable_memory_increase: 0 pages (no change)

  2. Decoding (scope):
    calls: 1 (no change)
    instructions: 44.56 M (0.00%) (change within noise threshold)
    heap_increase: 0 pages (no change)
    stable_memory_increase: 0 pages (no change)

---------------------------------------------------

Summary:
  instructions:
    status:   No significant changes 👍
    counts:   [total 20 | regressed 0 | improved 0 | new 0 | unchanged 20]
    change:   [max +4.43K | p75 +123 | median 0 | p25 0 | min -7.70K]
    change %: [max +0.02% | p75 0.00% | median 0.00% | p25 0.00% | min -0.01%]

  heap_increase:
    status:   No significant changes 👍
    counts:   [total 20 | regressed 0 | improved 0 | new 0 | unchanged 20]
    change:   [max 0 | p75 0 | median 0 | p25 0 | min 0]
    change %: [max 0.00% | p75 0.00% | median 0.00% | p25 0.00% | min 0.00%]

  stable_memory_increase:
    status:   No significant changes 👍
    counts:   [total 20 | regressed 0 | improved 0 | new 0 | unchanged 20]
    change:   [max 0 | p75 0 | median 0 | p25 0 | min 0]
    change %: [max 0.00% | p75 0.00% | median 0.00% | p25 0.00% | min 0.00%]

---------------------------------------------------
Successfully persisted results to canbench_results.yml

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR ports the named-argument parsing feature into candid_parser so downstream binding generators can preserve meaningful function parameter/result names in the parser AST, while keeping the candid crate’s core type model unchanged. It also adds small utilities to candid for deterministic type environment iteration and reusable pretty-print combinators, plus corresponding version bumps and golden test fixture updates.

Changes:

  • Introduces syntax::IDLArgType { typ, name } and updates function/class/arg containers in candid_parser to carry optional argument/result names, including grammar support and pretty-print round-tripping.
  • Adds pretty::utils::{sep_enclose, sep_enclose_space} and TypeEnv::to_sorted_iter() in candid, with crate version bumps and lockfile updates.
  • Updates didc and parser typing/tests to work with IDLArgType, and refreshes .did golden assets to reflect preserved names.

Reviewed changes

Copilot reviewed 17 out of 19 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
tools/didc/src/main.rs Adjusts type annotation parsing to use IDLArgType.typ.
rust/candid/src/types/type_env.rs Adds deterministic to_sorted_iter() iterator.
rust/candid/src/pretty/utils.rs Adds sep_enclose / sep_enclose_space pretty-print helpers.
rust/candid/Cargo.toml Bumps candid to 0.10.30 and syncs candid_derive dependency.
rust/candid_derive/Cargo.toml Bumps candid_derive to 0.10.30.
rust/candid_parser/Cargo.toml Bumps candid_parser to 0.4.0 (breaking).
rust/candid_parser/src/typing.rs Drops arg names during lowering/type-checking by using arg.typ.
rust/candid_parser/src/test.rs Updates test harness to pass IDLArgType.typ to type lowering.
rust/candid_parser/src/syntax/pretty.rs Pretty-prints named args/rets in function types and class constructors.
rust/candid_parser/src/syntax/mod.rs Introduces IDLArgType and updates AST containers to use it.
rust/candid_parser/src/grammar.lalrpop Parses named args and checks name uniqueness.
rust/candid_parser/tests/assets/ok/*.did Updates golden .did outputs to include preserved argument names.
CHANGELOG.md Documents releases for candid 0.10.30 and candid_parser 0.4.0.
Cargo.lock Updates workspace lock to new crate versions.
rust/bench/Cargo.lock Updates bench lock to new crate versions.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread rust/candid/src/pretty/utils.rs
Comment thread rust/candid_parser/src/syntax/mod.rs
Comment thread rust/candid_parser/src/grammar.lalrpop Outdated
- Use error2 with the tuple span for the duplicate named-argument check,
  consistent with the other uniqueness checks in the grammar (was error,
  which reports a 0..0 span). Drop the now-unused error import.
- Fix grammar typo in IDLArgType::new_with_name doc comment.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
@lwshang lwshang marked this pull request as ready for review June 23, 2026 16:43
@lwshang lwshang requested a review from a team as a code owner June 23, 2026 16:43
@zeropath-ai

zeropath-ai Bot commented Jun 23, 2026

Copy link
Copy Markdown

No security or compliance issues detected. Reviewed everything up to 39ad347.

Security Overview
Detected Code Changes

| Change Type | Relevant files

... (code changes summary truncated to fit VCS comment limits.)

@lwshang lwshang merged commit 34ae483 into master Jun 23, 2026
11 checks passed
@lwshang lwshang deleted the js-bindgen-named-args-parser branch June 23, 2026 17:37
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.

3 participants