diff --git a/CHANGELOG.md b/CHANGELOG.md index a52bb0833b..3f76dce094 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,7 +19,7 @@ incremented for features. * lang: Add `mint::freeze_authority` keyword for mint initialization within `#[derive(Accounts)]` ([#835](https://github.com/project-serum/anchor/pull/835)). * lang: Add `AccountLoader` type for `zero_copy` accounts with support for CPI ([#792](https://github.com/project-serum/anchor/pull/792)). * lang: Add `#[account(init_if_needed)]` keyword for allowing one to invoke the same instruction even if the account was created already ([#906](https://github.com/project-serum/anchor/pull/906)). -* lang: Add custom errors support for `signer`, `mut`, `has_one` and raw constraints ([#905](https://github.com/project-serum/anchor/pull/905), [#913](https://github.com/project-serum/anchor/pull/913)). +* lang: Add custom errors support for `signer`, `mut`, `has_one`, raw constraints and `address` ([#905](https://github.com/project-serum/anchor/pull/905), [#913](https://github.com/project-serum/anchor/pull/913)). ### Breaking diff --git a/lang/derive/accounts/src/lib.rs b/lang/derive/accounts/src/lib.rs index 45fc8ee0b0..7e4c7aa35f 100644 --- a/lang/derive/accounts/src/lib.rs +++ b/lang/derive/accounts/src/lib.rs @@ -50,7 +50,7 @@ use syn::parse_macro_input; /// | `#[account(executable)]` | On `AccountInfo` structs | Checks the given account is an executable program. | /// | `#[account(state = )]` | On `CpiState` structs | Checks the given state is the canonical state account for the target program. | /// | `#[account(owner = )]` | On `CpiState`, `CpiAccount`, and `AccountInfo` | Checks the account owner matches the target. | -/// | `#[account(address = )]` | On `AccountInfo` and `Account` | Checks the account key matches the pubkey. | +/// | `#[account(address = )]`

`#[account(address = @ )]` | On `AccountInfo` and `Account` | Checks the account key matches the pubkey. Custom errors are supported via `@`. | // TODO: How do we make the markdown render correctly without putting everything // on absurdly long lines? #[proc_macro_derive(Accounts, attributes(account, instruction))] diff --git a/lang/syn/src/codegen/accounts/constraints.rs b/lang/syn/src/codegen/accounts/constraints.rs index 027ad2f627..880d400afc 100644 --- a/lang/syn/src/codegen/accounts/constraints.rs +++ b/lang/syn/src/codegen/accounts/constraints.rs @@ -134,9 +134,10 @@ fn generate_constraint_composite(_f: &CompositeField, c: &Constraint) -> proc_ma fn generate_constraint_address(f: &Field, c: &ConstraintAddress) -> proc_macro2::TokenStream { let field = &f.ident; let addr = &c.address; + let error = generate_custom_error(&c.error, quote! { ConstraintAddress }); quote! { if #field.to_account_info().key != &#addr { - return Err(anchor_lang::__private::ErrorCode::ConstraintAddress.into()); + return Err(#error); } } } diff --git a/lang/syn/src/lib.rs b/lang/syn/src/lib.rs index ab557f8470..0e4a7067e9 100644 --- a/lang/syn/src/lib.rs +++ b/lang/syn/src/lib.rs @@ -639,6 +639,7 @@ pub struct ConstraintOwner { #[derive(Debug, Clone)] pub struct ConstraintAddress { pub address: Expr, + pub error: Option, } #[derive(Debug, Clone)] diff --git a/lang/syn/src/parser/accounts/constraints.rs b/lang/syn/src/parser/accounts/constraints.rs index e73a29b43f..6a4b9d0399 100644 --- a/lang/syn/src/parser/accounts/constraints.rs +++ b/lang/syn/src/parser/accounts/constraints.rs @@ -260,6 +260,7 @@ pub fn parse_token(stream: ParseStream) -> ParseResult { span, ConstraintAddress { address: stream.parse()?, + error: parse_optional_custom_error(&stream)?, }, )), _ => return Err(ParseError::new(ident.span(), "Invalid attribute")),