Skip to content

fix(lang/syn): allow destructure/wildcard patterns on Context arg#4469

Open
cryptomotifs wants to merge 1 commit into
otter-sec:masterfrom
cryptomotifs:fix/3838-destructure-context-pattern
Open

fix(lang/syn): allow destructure/wildcard patterns on Context arg#4469
cryptomotifs wants to merge 1 commit into
otter-sec:masterfrom
cryptomotifs:fix/3838-destructure-context-pattern

Conversation

@cryptomotifs
Copy link
Copy Markdown

Summary

Closes #3838.

parse_args previously rejected any argument whose pattern was not Pat::Ident. Combined with .ok()? in the instruction-collection loop, this caused instructions whose Context argument used a destructure or wildcard pattern to be silently filtered out of the program's IDL — no warning, no error.

Examples that previously produced an empty IDL:

#[program]
pub mod foobar {
    use super::*;

    pub fn initialize(Context { .. }: Context<Initialize>) -> Result<()> { Ok(()) }
    // and
    pub fn ping(_: Context<Ping>) -> Result<()> { Ok(()) }
}

Fix

Only the type of the Context argument matters for the derive macro — ctx_accounts_ident (in parser/program/mod.rs) reads path_ty.ty, never the pattern name. So we now:

  • Accept any pattern for the first argument (Context), and substitute a synthetic ctx identifier when it is not a Pat::Ident.
  • Continue to require a named Pat::Ident for subsequent (instruction) arguments, since those names appear in the generated IDL and codegen.

Diff

lang/syn/src/parser/program/instructions.rs::parse_args — 11 additions, 3 deletions.

Test plan

  • CI: existing test suite should pass unchanged (no semantics changed for the Pat::Ident path).
  • Local: I'd like a maintainer's preference on where to add the regression — I can extend tests/anchor-cli-idl with a program that uses Context { .. } and assert the IDL contains the instruction. Happy to follow up with a test commit if that placement works.

🤖 Generated with Claude Code

Closes otter-sec#3838.

`parse_args` rejected any argument whose pattern was not `Pat::Ident`,
which silently caused instructions whose `Context` argument used a
destructure (`Context { .. }: Context<T>`) or wildcard (`_: Context<T>`)
binding to be filtered out of the program's IDL. The error from
`parse_args` was swallowed by the `.ok()?` in the iterator that builds
the instruction list.

Only the type of the Context argument matters for the derive macro
(`ctx_accounts_ident` reads the type, not the pattern), so we accept any
pattern for the first argument and substitute a synthetic `ctx`
identifier. Subsequent (instruction) arguments still require a named
identifier, since their names appear in the generated IDL.

Repro that previously produced an empty IDL and now produces the
correct instruction:

    #[program]
    pub mod foobar {
        use super::*;

        pub fn initialize(Context { .. }: Context<Initialize>) -> Result<()> {
            Ok(())
        }
    }
@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 25, 2026

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

A member of the Team first needs to authorize it.

@jamie-osec
Copy link
Copy Markdown
Collaborator

@jamie-osec jamie-osec changed the title fix(lang/syn): allow destructure/wildcard patterns on Context arg (closes #3838) fix(lang/syn): allow destructure/wildcard patterns on Context arg May 13, 2026
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.

Destructure binding silently fails building IDL

2 participants