diff --git a/CHANGELOG.md b/CHANGELOG.md index b585dc0964..82a70b3b6c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,7 @@ The minor version will be incremented upon a breaking change and the patch versi - lang: Make stack frames slimmer on ATA creation ([#3065](https://github.com/coral-xyz/anchor/pull/3065)). - lang: Remove `getrandom` dependency ([#3072](https://github.com/coral-xyz/anchor/pull/3072)). - lang: Make `InitSpace` support unnamed & unit structs ([#3084](https://github.com/coral-xyz/anchor/pull/3084)). +- lang: Fix using `owner` constraint with `Box`ed accounts ([#3087](https://github.com/coral-xyz/anchor/pull/3087)). ### Breaking diff --git a/lang/syn/src/codegen/accounts/constraints.rs b/lang/syn/src/codegen/accounts/constraints.rs index 30bbbe85ea..78afe8227b 100644 --- a/lang/syn/src/codegen/accounts/constraints.rs +++ b/lang/syn/src/codegen/accounts/constraints.rs @@ -303,6 +303,13 @@ pub fn generate_constraint_raw(ident: &Ident, c: &ConstraintRaw) -> proc_macro2: pub fn generate_constraint_owner(f: &Field, c: &ConstraintOwner) -> proc_macro2::TokenStream { let ident = &f.ident; + let maybe_deref = match &f.ty { + Ty::Account(AccountTy { boxed, .. }) + | Ty::InterfaceAccount(InterfaceAccountTy { boxed, .. }) => *boxed, + _ => false, + } + .then(|| quote!(*)) + .unwrap_or_default(); let owner_address = &c.owner_address; let error = generate_custom_error( ident, @@ -310,9 +317,10 @@ pub fn generate_constraint_owner(f: &Field, c: &ConstraintOwner) -> proc_macro2: quote! { ConstraintOwner }, &Some(&(quote! { *my_owner }, quote! { owner_address })), ); + quote! { { - let my_owner = AsRef::::as_ref(&#ident).owner; + let my_owner = AsRef::::as_ref(& #maybe_deref #ident).owner; let owner_address = #owner_address; if my_owner != &owner_address { return #error; diff --git a/tests/misc/programs/misc/src/context.rs b/tests/misc/programs/misc/src/context.rs index 86748768dc..2944ca4bfb 100644 --- a/tests/misc/programs/misc/src/context.rs +++ b/tests/misc/programs/misc/src/context.rs @@ -1,4 +1,5 @@ use crate::account::*; +use crate::program::Misc; use anchor_lang::prelude::*; use anchor_spl::associated_token::AssociatedToken; use anchor_spl::token::{Mint, Token, TokenAccount}; @@ -803,3 +804,11 @@ pub struct InitManyAssociatedTokenAccounts<'info> { pub token_program: Program<'info, Token>, pub associated_token_program: Program<'info, AssociatedToken>, } + +#[derive(Accounts)] +pub struct TestBoxedOwnerConstraint<'info> { + // Redundant check to test compilation + #[account(owner = program.key())] + pub my_account: Box>, + pub program: Program<'info, Misc>, +} diff --git a/tests/misc/programs/misc/src/lib.rs b/tests/misc/programs/misc/src/lib.rs index bdb528b371..d6b32b9fe4 100644 --- a/tests/misc/programs/misc/src/lib.rs +++ b/tests/misc/programs/misc/src/lib.rs @@ -386,10 +386,14 @@ pub mod misc { Ok(()) } - #[allow(unused_variables)] pub fn test_init_many_associated_token_accounts( _ctx: Context, ) -> Result<()> { Ok(()) } + + /// Compilation test for https://github.com/coral-xyz/anchor/issues/3074 + pub fn test_boxed_owner_constraint(_ctx: Context) -> Result<()> { + Ok(()) + } }