Skip to content

fix(lang/syn): migrate anchor-syn and proc-macro crates to syn 2.0#4523

Merged
jamie-osec merged 4 commits into
otter-sec:masterfrom
eteen12:fix/syn2-crate-context-parse
May 14, 2026
Merged

fix(lang/syn): migrate anchor-syn and proc-macro crates to syn 2.0#4523
jamie-osec merged 4 commits into
otter-sec:masterfrom
eteen12:fix/syn2-crate-context-parse

Conversation

@eteen12

@eteen12 eteen12 commented May 12, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes #4521.

Upgrades syn from 1.x to 2.0 across anchor-syn and all dependent proc-macro crates:

  • lang/attribute/{program,account,access-control,error,event,constant}
  • lang/derive/{accounts,serde,space}

Key syn 2.0 breaking changes addressed

syn 1.x syn 2.x
attr.path (field) attr.path() (method)
attr.tokens (field) attr.meta / MetaList::tokens
NestedMeta syn::Meta
parse_meta() attr.meta
LifetimeDef LifetimeParam
Expr::Type FnArg::Typed
ParseMacroInput Parse
parse_terminated(f) parse_terminated(f, Token![,])

Removes the silent-fail bandaid from #4520

CrateContext::parse now hard-fails with an error message when it cannot parse the crate, rather than silently producing an incomplete IDL. This was only safe to remove because syn 2.0 can parse modern Rust syntax (e.g. impl Clone + use<T> precise-capture bounds from Rust 1.82+) that syn 1.x could not.

Regression test

Adds tests/idl-forward-ref — a minimal Anchor program that uses + use<T> precise-capture syntax. Building it with --features idl-build previously triggered the silent-fail path; it now compiles and generates correct IDL.

Test plan

  • cargo check -p anchor-syn — no errors
  • cargo check -p idl-forward-ref --features idl-build — no errors
  • cargo check -p anchor-attribute-{program,account,access-control,error,event,constant} -p anchor-derive-{accounts,serde,space} — no errors

Copilot AI review requested due to automatic review settings May 12, 2026 13:34
@vercel

vercel Bot commented May 12, 2026

Copy link
Copy Markdown

@eteen12 is attempting to deploy a commit to the Solana Foundation Team on Vercel.

A member of the Team first needs to authorize it.

@greptile-apps

greptile-apps Bot commented May 12, 2026

Copy link
Copy Markdown

Greptile Summary

This PR migrates anchor-syn and all dependent proc-macro crates from syn 1.x to 2.0, replacing deprecated API surface (attr.path field → attr.path() method, NestedMetasyn::Meta, LifetimeDefLifetimeParam, Expr::TypeFnArg::Typed, etc.) and removing the silent-fail bandaid from #4520 now that syn 2.0 can parse modern Rust syntax like precise-capture + use<T> bounds.

  • All syn 2.0 API migrations are mechanically correct; parse_terminated calls now pass the separator token as required, and attr.tokens accesses are properly replaced with attr.meta pattern matches.
  • CrateContext::parse now hard-fails (and caches the error) instead of silently producing an incomplete IDL, which is intentional and safe with syn 2.0.
  • A new regression-test crate (idl-forward-ref) proves the + use<T> parse path no longer fails.

Confidence Score: 4/5

The migration is mechanically correct throughout; the one concern worth resolving before merging is the removal of the Spanned trait impl from Context.

Every syn 2.0 API substitution looks correct. The Spanned trait impl removal from Context in anchor-syn (a published crate) will silently break downstream code that passes a Context where impl Spanned is expected, even though callers using the method directly are unaffected. The CRATE_DATA_CACHE hard-fail behaviour and the get_attr_str delimiter assumption are lower-stakes concerns.

lang/syn/src/lib.rs — the Spanned trait removal; lang/syn/src/idl/defined.rs — the delimiter assumption in get_attr_str

Important Files Changed

Filename Overview
lang/syn/src/lib.rs Core syn 2.0 migrations: parse_terminated separator added, instruction_api type changed from Punctuated<Expr> to Punctuated<FnArg>, trailing-comma handling moved to pop_punct(), and impl Spanned for Context<T> replaced with an inherent pub fn span() — a breaking change for downstream consumers.
lang/syn/src/idl/defined.rs CRATE_DATA_CACHE changed from OnceLock<Option<…>> (silent-fail) to OnceLock<Result<…, String>> (hard-fail); get_attr_str now only processes Meta::List variants, which is correct for repr and derive attrs in practice.
lang/syn/src/parser/context.rs Safety-check doc-comment detection and #[derive(Accounts)] filter both correctly migrated from tokenizer-level iteration to structured syn 2.0 Meta pattern matches.
lang/derive/serde/src/lib.rs extract_borsh_attrs migrated from NestedMeta to syn::Meta; silently swallows parse errors via unwrap_or_default(), matching the pre-existing silent behavior.
lang/syn/src/codegen/accounts/try_accounts.rs Expr::TypeFnArg::Typed migration is correct: arg.pat replaces expr_type.expr and arg.ty replaces expr_type.ty with equivalent quoting behavior.
lang/attribute/account/src/lib.rs #[accessor] and #[repr] attribute parsing migrated cleanly from token-stream iteration to structured attr.meta matching; bytemuck derive detection correctly scoped to derive attrs only.
lang/syn/src/parser/docs.rs Doc-comment extraction migrated from parse_meta() to direct attr.meta pattern matching; CHECK: filtering logic is preserved correctly.
lang/syn/src/parser/error.rs #[msg] and #[doc] attribute handling correctly migrated from token-stream group extraction to Meta::List::tokens.
tests/idl-forward-ref/programs/idl-forward-ref/src/lib.rs New regression test program using precise-capture + use<T> syntax and a forward-referenced type; correctly exercises the CRATE_DATA_CACHE path that previously triggered the silent-fail bug.

Sequence Diagram

sequenceDiagram
    participant PM as Proc-macro crate
    participant AS as anchor-syn
    participant CC as CrateContext::parse
    participant OL as OnceLock Cache

    PM->>AS: "gen_idl_type(Updates)"
    AS->>OL: get_or_init
    OL->>CC: "parse(&lib_path) via syn 2.0"
    CC-->>OL: "Ok(ctx) - handles use T syntax"
    OL-->>AS: "Ok(CachedCrateData)"
    AS-->>PM: "correct IDL tokens"

    Note over CC,OL: On parse failure
    CC-->>OL: "Err(e) - cached permanently"
    OL-->>AS: "Err(msg)"
    AS-->>PM: "compile_error! Failed to parse crate"
Loading

Reviews (1): Last reviewed commit: "fix(lang/syn): migrate anchor-syn and pr..." | Re-trigger Greptile

Comment thread lang/syn/src/lib.rs
Comment thread lang/syn/src/idl/defined.rs

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

Upgrades Anchor’s Rust parsing/codegen pipeline (anchor-syn and dependent proc-macro crates) from syn v1 to syn v2 to support modern Rust syntax during IDL generation, and restores hard-fail behavior when crate parsing cannot be performed.

Changes:

  • Migrate anchor-syn + proc-macro crates to syn = 2 and update parsing APIs (attr.path(), attr.meta, new parse_terminated signature, etc.).
  • Change IDL type generation to hard-error when CrateContext::parse fails (instead of silently falling back).
  • Add a regression test program (tests/idl-forward-ref) exercising Rust 1.82+ precise-capture syntax (+ use<T>).

Reviewed changes

Copilot reviewed 28 out of 29 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
tests/idl-forward-ref/programs/idl-forward-ref/src/lib.rs New minimal Anchor program reproducing forward-ref + IDL parsing scenario.
tests/idl-forward-ref/programs/idl-forward-ref/src/helper.rs New module using Rust 1.82+ precise-capture syntax for regression coverage.
tests/idl-forward-ref/programs/idl-forward-ref/Cargo.toml New test crate manifest with idl-build feature.
lang/syn/src/parser/program/instructions.rs Update attribute path handling for syn 2.
lang/syn/src/parser/error.rs Migrate error attribute parsing from token streams to attr.meta.
lang/syn/src/parser/docs.rs Migrate doc parsing to syn 2 MetaNameValue representation.
lang/syn/src/parser/context.rs Update safety-check attribute inspection and derive parsing to syn 2.
lang/syn/src/parser/accounts/mod.rs Switch #[instruction(...)] parsing to syn 2-compatible representation.
lang/syn/src/parser/accounts/constraints.rs Update attribute path handling for syn 2.
lang/syn/src/lib.rs syn 2 API updates (parse_terminated), instruction API type change, and Context span API change.
lang/syn/src/idl/defined.rs Update attribute token extraction and restore hard-fail on crate-parse errors (cached).
lang/syn/src/codegen/accounts/try_accounts.rs Adjust codegen for new instruction-arg representation.
lang/syn/src/codegen/accounts/mod.rs Update lifetime generic parsing to LifetimeParam.
lang/syn/Cargo.toml Bump syn dependency to v2.
lang/derive/space/src/lib.rs Update parsing helper to syn 2 parse_terminated API + path().
lang/derive/space/Cargo.toml Bump syn to v2 and enable needed features.
lang/derive/serde/src/lib.rs Replace NestedMeta usage with syn 2 Meta handling.
lang/derive/serde/Cargo.toml Bump syn to v2.
lang/derive/accounts/Cargo.toml Bump syn to v2.
lang/attribute/program/Cargo.toml Bump syn to v2.
lang/attribute/event/Cargo.toml Bump syn to v2.
lang/attribute/error/Cargo.toml Bump syn to v2.
lang/attribute/constant/Cargo.toml Bump syn to v2.
lang/attribute/account/src/lib.rs Update parsing/token handling to syn 2 meta/path().
lang/attribute/account/Cargo.toml Bump syn to v2.
lang/attribute/access-control/Cargo.toml Bump syn to v2.
CHANGELOG.md Document syn 2 migration + IDL generation fix.
Cargo.toml Add the new idl-forward-ref test crate to the workspace.
Cargo.lock Lockfile updates for syn 2 and new workspace member.

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

Comment thread lang/syn/src/parser/accounts/mod.rs
Comment thread lang/syn/src/lib.rs
Comment thread tests/idl-forward-ref/programs/idl-forward-ref/src/helper.rs Outdated
@eteen12

eteen12 commented May 12, 2026

Copy link
Copy Markdown
Contributor Author

fixed the issues the bots left for me

@eteen12

eteen12 commented May 12, 2026

Copy link
Copy Markdown
Contributor Author

working on passing the tests

@eteen12 eteen12 force-pushed the fix/syn2-crate-context-parse branch 3 times, most recently from 0c8c4cc to a4f69d3 Compare May 12, 2026 18:26
@jamie-osec

Copy link
Copy Markdown
Collaborator

Can you additionally move syn to workspace.dependencies to avoid versions desyncing?

@eteen12 eteen12 force-pushed the fix/syn2-crate-context-parse branch from a4f69d3 to f2a48e5 Compare May 12, 2026 18:50
Fixes otter-sec#4521.

Upgrades syn from 1.x to 2.0 across anchor-syn and all dependent
proc-macro crates:
- lang/attribute/{program,account,access-control,error,event,constant}
- lang/derive/{accounts,serde,space}

Key syn 2.0 breaking changes addressed:
- attr.path (field) -> attr.path() (method)
- attr.tokens (field) -> attr.meta / MetaList::tokens
- NestedMeta -> syn::Meta
- parse_meta() -> attr.meta
- LifetimeDef -> LifetimeParam
- Expr::Type -> FnArg::Typed
- ParseMacroInput -> Parse
- parse_terminated(f) -> parse_terminated(f, Token![,])

CrateContext::parse now hard-fails on parse errors instead of silently
producing an incomplete IDL. Only safe because syn 2.0 can parse modern
Rust syntax (e.g. `impl Clone + use<T>` precise-capture bounds from
Rust 1.82+) that syn 1.x could not, which removes the need for the
silent-fail bandaid from otter-sec#4520.

Adds tests/idl-forward-ref as a regression test — a minimal Anchor
program that uses `+ use<T>` precise-capture syntax. Building it with
--features idl-build previously hit the silent-fail path; it now
compiles and generates correct IDL. Marked publish=false so the
release dry-run stays green.

Drive-by clippy fixes in lang/syn:
- replace direct slice indexing in parse_migration_ty, parse_account,
  parse_program_account, and parse_sysvar with .first()/.get() plus
  proper error propagation (clippy::indexing_slicing)
- replace map_or(false, ...) with is_some_and(...) in context.rs
  (clippy::unnecessary_map_or)
@eteen12 eteen12 force-pushed the fix/syn2-crate-context-parse branch from f2a48e5 to b049ad8 Compare May 12, 2026 19:43
@eteen12

eteen12 commented May 12, 2026

Copy link
Copy Markdown
Contributor Author

@jamie-osec sure thing, made the changes and lets see if i pass all CI tests 🤞

@eteen12

eteen12 commented May 12, 2026

Copy link
Copy Markdown
Contributor Author

all tests passed and ready for review

Comment thread CHANGELOG.md Outdated
Comment thread tests/idl-forward-ref/programs/idl-forward-ref/src/helper.rs Outdated
@jamie-osec

Copy link
Copy Markdown
Collaborator

Directionally looks good, please address the review comments by me and the AIs.

eteen12 and others added 3 commits May 13, 2026 14:07
Co-authored-by: Jamie Hill-Daniel <134328753+jamie-osec@users.noreply.github.com>
moves the precise-capture regression case out of the standalone
`tests/idl-forward-ref/` crate (which wasn't picked up by the GHA
matrix) and into `tests/idl/programs/generics/` as a private `helper`
module.

CI runs `cd tests/idl && ./test.sh`, which builds the generics program
and calls `anchor idl build` on it. that walks every `.rs` in the crate
via `CrateContext::parse`, so the `+ use<T>` syntax now actually gets
exercised in CI — if syn ever regresses on it, IDL build fails.
@eteen12 eteen12 requested a review from jamie-osec May 13, 2026 21:39
snawaz added a commit to magicblock-labs/ephemeral-rollups-sdk that referenced this pull request May 14, 2026
- Turned out that `anchor-syn 1.0` depends on `syn 1.0`, which is quite old and does not understand newer Rust syntax such as `const {}` blocks. As a result, I had to remove them from `as_modern.rs` (which unfortunately turns those assertions from compile-time asserts into runtime asserts 😞 ).
  - Interestingly, there is [an issue created on anchor repo](otter-sec/anchor#4521) just 2 days back and [a PR that upgrades to `syn 2.0`](otter-sec/anchor#4523).
- Made changes such that **30 out of 32 sensible feature combinations** now build successfully. See `sdk/scripts/test-combinations.sh`, which is now also executed by CI.
  - The remaining 2 combinations fail when `anchor-debug` feature is enabled. This appears to be an `anchor-lang 0.32.0` issue when that feature is enabled. Since it is not a particularly important feature  (and any user of anchor 0.32 will face this problem anyway), this is acceptable for now.
  
 

https://github.com/user-attachments/assets/b51e8ab9-a81a-4a29-910c-a12a68b90b1c



<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

* **Refactor**
  * Reorganized internal feature flag definitions for better modularity.
  * Streamlined serialization configuration for core data structures.
  * Consolidated PDA helper imports to improve code organization.

* **Chores**
  * Added automated testing across multiple feature combinations to ensure compatibility.

<!-- review_stack_entry_start -->

[![Review Change Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/magicblock-labs/ephemeral-rollups-sdk/pull/217)

<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
@jamie-osec jamie-osec merged commit 4addac5 into otter-sec:master May 14, 2026
68 of 69 checks passed
Dodecahedr0x pushed a commit to magicblock-labs/ephemeral-rollups-sdk that referenced this pull request May 18, 2026
- Turned out that `anchor-syn 1.0` depends on `syn 1.0`, which is quite old and does not understand newer Rust syntax such as `const {}` blocks. As a result, I had to remove them from `as_modern.rs` (which unfortunately turns those assertions from compile-time asserts into runtime asserts 😞 ).
  - Interestingly, there is [an issue created on anchor repo](otter-sec/anchor#4521) just 2 days back and [a PR that upgrades to `syn 2.0`](otter-sec/anchor#4523).
- Made changes such that **30 out of 32 sensible feature combinations** now build successfully. See `sdk/scripts/test-combinations.sh`, which is now also executed by CI.
  - The remaining 2 combinations fail when `anchor-debug` feature is enabled. This appears to be an `anchor-lang 0.32.0` issue when that feature is enabled. Since it is not a particularly important feature  (and any user of anchor 0.32 will face this problem anyway), this is acceptable for now.
  
 

https://github.com/user-attachments/assets/b51e8ab9-a81a-4a29-910c-a12a68b90b1c



<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

* **Refactor**
  * Reorganized internal feature flag definitions for better modularity.
  * Streamlined serialization configuration for core data structures.
  * Consolidated PDA helper imports to improve code organization.

* **Chores**
  * Added automated testing across multiple feature combinations to ensure compatibility.

<!-- review_stack_entry_start -->

[![Review Change Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/magicblock-labs/ephemeral-rollups-sdk/pull/217)

<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
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.

chore(lang/syn): migrate CrateContext::parse from syn 1.x to syn 2.0

3 participants