lang: Add zero attribute (#513)
This commit is contained in:
parent
142728d271
commit
2604a442fd
|
@ -83,7 +83,7 @@ pub mod cashiers_check {
|
|||
#[derive(Accounts)]
|
||||
pub struct CreateCheck<'info> {
|
||||
// Check being created.
|
||||
#[account(init)]
|
||||
#[account(zero)]
|
||||
check: ProgramAccount<'info, Check>,
|
||||
// Check's token vault.
|
||||
#[account(mut, "&vault.owner == check_signer.key")]
|
||||
|
|
|
@ -53,7 +53,7 @@ pub struct CreateUser<'info> {
|
|||
|
||||
#[derive(Accounts)]
|
||||
pub struct CreateChatRoom<'info> {
|
||||
#[account(init)]
|
||||
#[account(zero)]
|
||||
chat_room: Loader<'info, ChatRoom>,
|
||||
}
|
||||
|
||||
|
|
|
@ -27,9 +27,9 @@ mod composite {
|
|||
|
||||
#[derive(Accounts)]
|
||||
pub struct Initialize<'info> {
|
||||
#[account(init)]
|
||||
#[account(zero)]
|
||||
pub dummy_a: ProgramAccount<'info, DummyA>,
|
||||
#[account(init)]
|
||||
#[account(zero)]
|
||||
pub dummy_b: ProgramAccount<'info, DummyB>,
|
||||
}
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ pub struct MutError<'info> {
|
|||
|
||||
#[derive(Accounts)]
|
||||
pub struct HasOneError<'info> {
|
||||
#[account(init, has_one = owner)]
|
||||
#[account(zero, has_one = owner)]
|
||||
my_account: ProgramAccount<'info, HasOneAccount>,
|
||||
owner: AccountInfo<'info>,
|
||||
}
|
||||
|
|
|
@ -106,7 +106,7 @@ pub struct InitializeEscrow<'info> {
|
|||
)]
|
||||
pub initializer_deposit_token_account: CpiAccount<'info, TokenAccount>,
|
||||
pub initializer_receive_token_account: CpiAccount<'info, TokenAccount>,
|
||||
#[account(init)]
|
||||
#[account(zero)]
|
||||
pub escrow_account: ProgramAccount<'info, EscrowAccount>,
|
||||
pub token_program: AccountInfo<'info>,
|
||||
}
|
||||
|
|
|
@ -191,7 +191,7 @@ pub mod ido_pool {
|
|||
|
||||
#[derive(Accounts)]
|
||||
pub struct InitializePool<'info> {
|
||||
#[account(init)]
|
||||
#[account(zero)]
|
||||
pub pool_account: ProgramAccount<'info, PoolAccount>,
|
||||
pub pool_signer: AccountInfo<'info>,
|
||||
#[account(
|
||||
|
|
|
@ -207,7 +207,7 @@ pub struct Auth<'info> {
|
|||
#[derive(Accounts)]
|
||||
pub struct CreateVesting<'info> {
|
||||
// Vesting.
|
||||
#[account(init)]
|
||||
#[account(zero)]
|
||||
vesting: ProgramAccount<'info, Vesting>,
|
||||
#[account(mut)]
|
||||
vault: CpiAccount<'info, TokenAccount>,
|
||||
|
|
|
@ -556,9 +556,9 @@ mod registry {
|
|||
|
||||
#[derive(Accounts)]
|
||||
pub struct Initialize<'info> {
|
||||
#[account(init)]
|
||||
#[account(zero)]
|
||||
registrar: ProgramAccount<'info, Registrar>,
|
||||
#[account(init)]
|
||||
#[account(zero)]
|
||||
reward_event_q: ProgramAccount<'info, RewardQueue>,
|
||||
#[account("pool_mint.decimals == 0")]
|
||||
pool_mint: CpiAccount<'info, Mint>,
|
||||
|
@ -595,7 +595,7 @@ pub struct CreateMember<'info> {
|
|||
// Stake instance.
|
||||
registrar: ProgramAccount<'info, Registrar>,
|
||||
// Member.
|
||||
#[account(init)]
|
||||
#[account(zero)]
|
||||
member: ProgramAccount<'info, Member>,
|
||||
#[account(signer)]
|
||||
beneficiary: AccountInfo<'info>,
|
||||
|
@ -790,7 +790,7 @@ pub struct StartUnstake<'info> {
|
|||
pool_mint: AccountInfo<'info>,
|
||||
|
||||
// Member.
|
||||
#[account(init)]
|
||||
#[account(zero)]
|
||||
pending_withdrawal: ProgramAccount<'info, PendingWithdrawal>,
|
||||
#[account(has_one = beneficiary, has_one = registrar)]
|
||||
member: ProgramAccount<'info, Member>,
|
||||
|
@ -924,7 +924,7 @@ pub struct DropReward<'info> {
|
|||
reward_event_q: ProgramAccount<'info, RewardQueue>,
|
||||
pool_mint: CpiAccount<'info, Mint>,
|
||||
// Vendor.
|
||||
#[account(init)]
|
||||
#[account(zero)]
|
||||
vendor: ProgramAccount<'info, RewardVendor>,
|
||||
#[account(mut)]
|
||||
vendor_vault: CpiAccount<'info, TokenAccount>,
|
||||
|
|
|
@ -75,7 +75,7 @@ pub struct RemainingAccounts {}
|
|||
|
||||
#[derive(Accounts)]
|
||||
pub struct Initialize<'info> {
|
||||
#[account(init)]
|
||||
#[account(zero)]
|
||||
pub data: ProgramAccount<'info, Data>,
|
||||
}
|
||||
|
||||
|
@ -111,13 +111,13 @@ pub struct TestClose<'info> {
|
|||
|
||||
#[derive(Accounts)]
|
||||
pub struct TestU16<'info> {
|
||||
#[account(init)]
|
||||
#[account(zero)]
|
||||
pub my_account: ProgramAccount<'info, DataU16>,
|
||||
}
|
||||
|
||||
#[derive(Accounts)]
|
||||
pub struct TestI16<'info> {
|
||||
#[account(init)]
|
||||
#[account(zero)]
|
||||
pub data: ProgramAccount<'info, DataI16>,
|
||||
}
|
||||
|
||||
|
|
|
@ -164,14 +164,14 @@ pub mod multisig {
|
|||
|
||||
#[derive(Accounts)]
|
||||
pub struct CreateMultisig<'info> {
|
||||
#[account(init)]
|
||||
#[account(zero)]
|
||||
multisig: ProgramAccount<'info, Multisig>,
|
||||
}
|
||||
|
||||
#[derive(Accounts)]
|
||||
pub struct CreateTransaction<'info> {
|
||||
multisig: ProgramAccount<'info, Multisig>,
|
||||
#[account(init)]
|
||||
#[account(zero)]
|
||||
transaction: ProgramAccount<'info, Transaction>,
|
||||
// One of the owners. Checked in the handler.
|
||||
#[account(signer)]
|
||||
|
|
|
@ -19,7 +19,7 @@ mod basic_1 {
|
|||
|
||||
#[derive(Accounts)]
|
||||
pub struct Initialize<'info> {
|
||||
#[account(init)]
|
||||
#[account(zero)]
|
||||
pub my_account: ProgramAccount<'info, MyAccount>,
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ mod basic_2 {
|
|||
|
||||
#[derive(Accounts)]
|
||||
pub struct Create<'info> {
|
||||
#[account(init)]
|
||||
#[account(zero)]
|
||||
pub counter: ProgramAccount<'info, Counter>,
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ pub mod puppet {
|
|||
|
||||
#[derive(Accounts)]
|
||||
pub struct Initialize<'info> {
|
||||
#[account(init)]
|
||||
#[account(zero)]
|
||||
pub puppet: ProgramAccount<'info, Puppet>,
|
||||
}
|
||||
|
||||
|
|
|
@ -109,7 +109,7 @@ pub struct SetEvent<'info> {
|
|||
|
||||
#[derive(Accounts)]
|
||||
pub struct CreateFoo<'info> {
|
||||
#[account(init)]
|
||||
#[account(zero)]
|
||||
foo: Loader<'info, Foo>,
|
||||
#[account(signer)]
|
||||
authority: AccountInfo<'info>,
|
||||
|
@ -165,7 +165,7 @@ pub struct UpdateBar<'info> {
|
|||
|
||||
#[derive(Accounts)]
|
||||
pub struct CreateLargeAccount<'info> {
|
||||
#[account(init)]
|
||||
#[account(zero)]
|
||||
event_q: Loader<'info, EventQ>,
|
||||
}
|
||||
|
||||
|
|
|
@ -1,9 +1,4 @@
|
|||
use crate::{
|
||||
CompositeField, Constraint, ConstraintAddress, ConstraintClose, ConstraintExecutable,
|
||||
ConstraintGroup, ConstraintHasOne, ConstraintInit, ConstraintLiteral, ConstraintMut,
|
||||
ConstraintOwner, ConstraintRaw, ConstraintRentExempt, ConstraintSeedsGroup, ConstraintSigner,
|
||||
ConstraintState, Field, PdaKind, Ty,
|
||||
};
|
||||
use crate::*;
|
||||
use proc_macro2_diagnostics::SpanDiagnosticExt;
|
||||
use quote::quote;
|
||||
use syn::Expr;
|
||||
|
@ -48,6 +43,7 @@ pub fn generate_composite(f: &CompositeField) -> proc_macro2::TokenStream {
|
|||
pub fn linearize(c_group: &ConstraintGroup) -> Vec<Constraint> {
|
||||
let ConstraintGroup {
|
||||
init,
|
||||
zeroed,
|
||||
mutable,
|
||||
signer,
|
||||
has_one,
|
||||
|
@ -70,6 +66,9 @@ pub fn linearize(c_group: &ConstraintGroup) -> Vec<Constraint> {
|
|||
if let Some(c) = init {
|
||||
constraints.push(Constraint::Init(c));
|
||||
}
|
||||
if let Some(c) = zeroed {
|
||||
constraints.push(Constraint::Zeroed(c));
|
||||
}
|
||||
if let Some(c) = mutable {
|
||||
constraints.push(Constraint::Mut(c));
|
||||
}
|
||||
|
@ -103,6 +102,7 @@ pub fn linearize(c_group: &ConstraintGroup) -> Vec<Constraint> {
|
|||
fn generate_constraint(f: &Field, c: &Constraint) -> proc_macro2::TokenStream {
|
||||
match c {
|
||||
Constraint::Init(c) => generate_constraint_init(f, c),
|
||||
Constraint::Zeroed(c) => generate_constraint_zeroed(f, c),
|
||||
Constraint::Mut(c) => generate_constraint_mut(f, c),
|
||||
Constraint::HasOne(c) => generate_constraint_has_one(f, c),
|
||||
Constraint::Signer(c) => generate_constraint_signer(f, c),
|
||||
|
@ -140,6 +140,12 @@ pub fn generate_constraint_init(_f: &Field, _c: &ConstraintInit) -> proc_macro2:
|
|||
quote! {}
|
||||
}
|
||||
|
||||
pub fn generate_constraint_zeroed(_f: &Field, _c: &ConstraintZeroed) -> proc_macro2::TokenStream {
|
||||
// No constraint. The zero discriminator is checked in `try_accounts_init`
|
||||
// currently.
|
||||
quote! {}
|
||||
}
|
||||
|
||||
pub fn generate_constraint_close(f: &Field, c: &ConstraintClose) -> proc_macro2::TokenStream {
|
||||
let field = &f.ident;
|
||||
let target = &c.sol_dest;
|
||||
|
|
|
@ -38,7 +38,7 @@ pub fn generate(accs: &AccountsStruct) -> proc_macro2::TokenStream {
|
|||
}
|
||||
} else {
|
||||
let name = typed_ident(f);
|
||||
match f.constraints.is_init() {
|
||||
match f.constraints.is_init() || f.constraints.is_zeroed() {
|
||||
false => quote! {
|
||||
#[cfg(feature = "anchor-debug")]
|
||||
::solana_program::log::sol_log(stringify!(#name));
|
||||
|
|
|
@ -263,6 +263,7 @@ pub struct ErrorCode {
|
|||
#[derive(Debug, Default, Clone)]
|
||||
pub struct ConstraintGroup {
|
||||
init: Option<ConstraintInit>,
|
||||
zeroed: Option<ConstraintZeroed>,
|
||||
mutable: Option<ConstraintMut>,
|
||||
signer: Option<ConstraintSigner>,
|
||||
owner: Option<ConstraintOwner>,
|
||||
|
@ -282,6 +283,10 @@ impl ConstraintGroup {
|
|||
self.init.is_some()
|
||||
}
|
||||
|
||||
pub fn is_zeroed(&self) -> bool {
|
||||
self.zeroed.is_some()
|
||||
}
|
||||
|
||||
pub fn is_mutable(&self) -> bool {
|
||||
self.mutable.is_some()
|
||||
}
|
||||
|
@ -302,6 +307,7 @@ impl ConstraintGroup {
|
|||
#[derive(Debug)]
|
||||
pub enum Constraint {
|
||||
Init(ConstraintInit),
|
||||
Zeroed(ConstraintZeroed),
|
||||
Mut(ConstraintMut),
|
||||
Signer(ConstraintSigner),
|
||||
HasOne(ConstraintHasOne),
|
||||
|
@ -321,6 +327,7 @@ pub enum Constraint {
|
|||
#[derive(Debug)]
|
||||
pub enum ConstraintToken {
|
||||
Init(Context<ConstraintInit>),
|
||||
Zeroed(Context<ConstraintZeroed>),
|
||||
Mut(Context<ConstraintMut>),
|
||||
Signer(Context<ConstraintSigner>),
|
||||
HasOne(Context<ConstraintHasOne>),
|
||||
|
@ -351,6 +358,9 @@ impl Parse for ConstraintToken {
|
|||
#[derive(Debug, Clone)]
|
||||
pub struct ConstraintInit {}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ConstraintZeroed {}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ConstraintMut {}
|
||||
|
||||
|
|
|
@ -62,6 +62,7 @@ pub fn parse_token(stream: ParseStream) -> ParseResult<ConstraintToken> {
|
|||
|
||||
let c = match kw.as_str() {
|
||||
"init" => ConstraintToken::Init(Context::new(ident.span(), ConstraintInit {})),
|
||||
"zero" => ConstraintToken::Zeroed(Context::new(ident.span(), ConstraintZeroed {})),
|
||||
"mut" => ConstraintToken::Mut(Context::new(ident.span(), ConstraintMut {})),
|
||||
"signer" => ConstraintToken::Signer(Context::new(ident.span(), ConstraintSigner {})),
|
||||
"executable" => {
|
||||
|
@ -229,6 +230,7 @@ pub fn parse_token(stream: ParseStream) -> ParseResult<ConstraintToken> {
|
|||
pub struct ConstraintGroupBuilder<'ty> {
|
||||
pub f_ty: Option<&'ty Ty>,
|
||||
pub init: Option<Context<ConstraintInit>>,
|
||||
pub zeroed: Option<Context<ConstraintZeroed>>,
|
||||
pub mutable: Option<Context<ConstraintMut>>,
|
||||
pub signer: Option<Context<ConstraintSigner>>,
|
||||
pub has_one: Vec<Context<ConstraintHasOne>>,
|
||||
|
@ -255,6 +257,7 @@ impl<'ty> ConstraintGroupBuilder<'ty> {
|
|||
Self {
|
||||
f_ty,
|
||||
init: None,
|
||||
zeroed: None,
|
||||
mutable: None,
|
||||
signer: None,
|
||||
has_one: Vec::new(),
|
||||
|
@ -290,6 +293,7 @@ impl<'ty> ConstraintGroupBuilder<'ty> {
|
|||
.mutable
|
||||
.replace(Context::new(i.span(), ConstraintMut {})),
|
||||
};
|
||||
// Rent exempt if not explicitly skipped.
|
||||
if self.rent_exempt.is_none() {
|
||||
self.rent_exempt
|
||||
.replace(Context::new(i.span(), ConstraintRentExempt::Enforce));
|
||||
|
@ -297,6 +301,25 @@ impl<'ty> ConstraintGroupBuilder<'ty> {
|
|||
}
|
||||
|
||||
// Seeds.
|
||||
if let Some(z) = &self.zeroed {
|
||||
match self.mutable {
|
||||
Some(m) => {
|
||||
return Err(ParseError::new(
|
||||
m.span(),
|
||||
"mut cannot be provided with zeroed",
|
||||
))
|
||||
}
|
||||
None => self
|
||||
.mutable
|
||||
.replace(Context::new(z.span(), ConstraintMut {})),
|
||||
};
|
||||
// Rent exempt if not explicitly skipped.
|
||||
if self.rent_exempt.is_none() {
|
||||
self.rent_exempt
|
||||
.replace(Context::new(z.span(), ConstraintRentExempt::Enforce));
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(i) = &self.seeds {
|
||||
if self.init.is_some() && self.payer.is_none() {
|
||||
return Err(ParseError::new(
|
||||
|
@ -365,6 +388,7 @@ impl<'ty> ConstraintGroupBuilder<'ty> {
|
|||
let ConstraintGroupBuilder {
|
||||
f_ty: _,
|
||||
init,
|
||||
zeroed,
|
||||
mutable,
|
||||
signer,
|
||||
has_one,
|
||||
|
@ -413,6 +437,7 @@ impl<'ty> ConstraintGroupBuilder<'ty> {
|
|||
let is_init = init.is_some();
|
||||
Ok(ConstraintGroup {
|
||||
init: into_inner!(init),
|
||||
zeroed: into_inner!(zeroed),
|
||||
mutable: into_inner!(mutable),
|
||||
signer: into_inner!(signer),
|
||||
has_one: into_inner_vec!(has_one),
|
||||
|
@ -469,6 +494,7 @@ impl<'ty> ConstraintGroupBuilder<'ty> {
|
|||
pub fn add(&mut self, c: ConstraintToken) -> ParseResult<()> {
|
||||
match c {
|
||||
ConstraintToken::Init(c) => self.add_init(c),
|
||||
ConstraintToken::Zeroed(c) => self.add_zeroed(c),
|
||||
ConstraintToken::Mut(c) => self.add_mut(c),
|
||||
ConstraintToken::Signer(c) => self.add_signer(c),
|
||||
ConstraintToken::HasOne(c) => self.add_has_one(c),
|
||||
|
@ -495,10 +521,24 @@ impl<'ty> ConstraintGroupBuilder<'ty> {
|
|||
if self.init.is_some() {
|
||||
return Err(ParseError::new(c.span(), "init already provided"));
|
||||
}
|
||||
if self.zeroed.is_some() {
|
||||
return Err(ParseError::new(c.span(), "zeroed already provided"));
|
||||
}
|
||||
self.init.replace(c);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn add_zeroed(&mut self, c: Context<ConstraintZeroed>) -> ParseResult<()> {
|
||||
if self.zeroed.is_some() {
|
||||
return Err(ParseError::new(c.span(), "zeroed already provided"));
|
||||
}
|
||||
if self.init.is_some() {
|
||||
return Err(ParseError::new(c.span(), "init already provided"));
|
||||
}
|
||||
self.zeroed.replace(c);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn add_close(&mut self, c: Context<ConstraintClose>) -> ParseResult<()> {
|
||||
if !matches!(self.f_ty, Some(Ty::ProgramAccount(_)))
|
||||
&& !matches!(self.f_ty, Some(Ty::Loader(_)))
|
||||
|
@ -700,7 +740,7 @@ impl<'ty> ConstraintGroupBuilder<'ty> {
|
|||
if self.seeds.is_none() {
|
||||
return Err(ParseError::new(
|
||||
c.span(),
|
||||
"associated or seeds must be provided before space",
|
||||
"init must be provided before space",
|
||||
));
|
||||
}
|
||||
if self.space.is_some() {
|
||||
|
|
Loading…
Reference in New Issue