Skip to content

Commit 83908d7

Browse files
lang: Fix instructions with no accounts causing compilation errors when using declare_program! (otter-sec#3567)
1 parent d182e15 commit 83908d7

4 files changed

Lines changed: 31 additions & 1 deletion

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ The minor version will be incremented upon a breaking change and the patch versi
116116
- idl: Fix using constant identifiers as generic arguments ([#3522](https://github.com/coral-xyz/anchor/pull/3522)).
117117
- client: Remove `std::process::exit` usage ([#3544](https://github.com/coral-xyz/anchor/pull/3544)).
118118
- idl: Fix using `Pubkey` constants with `seeds::program` ([#3559](https://github.com/coral-xyz/anchor/pull/3559)).
119+
- lang: Fix instructions with no accounts causing compilation errors when using `declare_program!` ([#3567](https://github.com/coral-xyz/anchor/pull/3567)).
119120

120121
### Breaking
121122

lang/attribute/program/src/declare_program/mods/cpi.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,12 @@ fn gen_cpi_instructions(idl: &Idl) -> proc_macro2::TokenStream {
2626
let method_name = format_ident!("{}", ix.name);
2727
let accounts_ident = format_ident!("{}", ix.name.to_camel_case());
2828

29+
let accounts_generic = if ix.accounts.is_empty() {
30+
quote!()
31+
} else {
32+
quote!(<'info>)
33+
};
34+
2935
let args = ix.args.iter().map(|arg| {
3036
let name = format_ident!("{}", arg.name);
3137
let ty = convert_idl_type_to_syn_type(&arg.ty);
@@ -61,7 +67,7 @@ fn gen_cpi_instructions(idl: &Idl) -> proc_macro2::TokenStream {
6167

6268
quote! {
6369
pub fn #method_name<'a, 'b, 'c, 'info>(
64-
ctx: anchor_lang::context::CpiContext<'a, 'b, 'c, 'info, accounts::#accounts_ident<'info>>,
70+
ctx: anchor_lang::context::CpiContext<'a, 'b, 'c, 'info, accounts::#accounts_ident #accounts_generic>,
6571
#(#args),*
6672
) -> #ret_type {
6773
let ix = {

tests/declare-program/idls/external.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,21 @@
7373
}
7474
]
7575
},
76+
{
77+
"name": "test_compilation_no_accounts",
78+
"discriminator": [
79+
194,
80+
91,
81+
205,
82+
217,
83+
51,
84+
10,
85+
247,
86+
201
87+
],
88+
"accounts": [],
89+
"args": []
90+
},
7691
{
7792
"name": "test_compilation_return_type",
7893
"discriminator": [

tests/declare-program/programs/external/src/lib.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,21 @@ pub mod external {
4545
pub fn test_compilation_return_type(_ctx: Context<TestCompilation>) -> Result<bool> {
4646
Ok(true)
4747
}
48+
49+
// Compilation test for an instruction with no accounts
50+
pub fn test_compilation_no_accounts(_ctx: Context<TestCompilationNoAccounts>) -> Result<()> {
51+
Ok(())
52+
}
4853
}
4954

5055
#[derive(Accounts)]
5156
pub struct TestCompilation<'info> {
5257
pub signer: Signer<'info>,
5358
}
5459

60+
#[derive(Accounts)]
61+
pub struct TestCompilationNoAccounts {}
62+
5563
#[derive(Accounts)]
5664
pub struct Init<'info> {
5765
#[account(mut)]

0 commit comments

Comments
 (0)