浏览代码

lang: remove deprecated accounts (#2375)

Jean Marchand (Exotic Markets) 2 年之前
父节点
当前提交
c76641f861

+ 1 - 0
CHANGELOG.md

@@ -30,6 +30,7 @@ The minor version will be incremented upon a breaking change and the patch versi
 
 ### Breaking
 
+- lang: Remove deprecated account types: `CpiAccount`, `Loader` and `ProgramAccount` ([#2375](https://github.com/coral-xyz/anchor/pull/2375)).
 - lang: Remove `state` and `interface` attributes ([#2285](https://github.com/coral-xyz/anchor/pull/2285)).
 - lang: `account(zero_copy)` and `zero_copy` attributes now derive the `bytemuck::Pod` and `bytemuck::Zeroable` traits instead of using `unsafe impl` ([#2330](https://github.com/coral-xyz/anchor/pull/2330)). This imposes useful restrictions on the type, like not having padding bytes and all fields being `Pod` themselves. See [bytemuck::Pod](https://docs.rs/bytemuck/latest/bytemuck/trait.Pod.html) for details. This change requires adding `bytemuck = { version = "1.4.0", features = ["derive", "min_const_generics"]}` to your `cargo.toml`. Legacy applications can still use `#[account(zero_copy(unsafe))]` and `#[zero_copy(unsafe)]` for the old behavior.
 - ts: Remove `createProgramAddressSync`, `findProgramAddressSync` (now available in `@solana/web3.js`) and update `associatedAddress` to be synchronous ([#2357](https://github.com/coral-xyz/anchor/pull/2357)).

+ 0 - 129
lang/src/accounts/cpi_account.rs

@@ -1,129 +0,0 @@
-use crate::*;
-use crate::{error::ErrorCode, prelude::Account};
-use solana_program::account_info::AccountInfo;
-use solana_program::instruction::AccountMeta;
-use solana_program::pubkey::Pubkey;
-use std::collections::BTreeMap;
-use std::ops::{Deref, DerefMut};
-
-/// Container for any account *not* owned by the current program.
-#[derive(Clone)]
-#[deprecated(since = "0.15.0", note = "Please use Account instead")]
-pub struct CpiAccount<'a, T: AccountDeserialize + Clone> {
-    info: AccountInfo<'a>,
-    account: Box<T>,
-}
-
-#[allow(deprecated)]
-impl<'a, T: AccountDeserialize + Clone> CpiAccount<'a, T> {
-    fn new(info: AccountInfo<'a>, account: Box<T>) -> CpiAccount<'a, T> {
-        Self { info, account }
-    }
-
-    /// Deserializes the given `info` into a `CpiAccount`.
-    pub fn try_from(info: &AccountInfo<'a>) -> Result<CpiAccount<'a, T>> {
-        let mut data: &[u8] = &info.try_borrow_data()?;
-        Ok(CpiAccount::new(
-            info.clone(),
-            Box::new(T::try_deserialize(&mut data)?),
-        ))
-    }
-
-    pub fn try_from_unchecked(info: &AccountInfo<'a>) -> Result<CpiAccount<'a, T>> {
-        Self::try_from(info)
-    }
-
-    /// Reloads the account from storage. This is useful, for example, when
-    /// observing side effects after CPI.
-    pub fn reload(&mut self) -> Result<()> {
-        let mut data: &[u8] = &self.info.try_borrow_data()?;
-        self.account = Box::new(T::try_deserialize(&mut data)?);
-        Ok(())
-    }
-}
-
-#[allow(deprecated)]
-impl<'info, T> Accounts<'info> for CpiAccount<'info, T>
-where
-    T: AccountDeserialize + Clone,
-{
-    #[inline(never)]
-    fn try_accounts(
-        _program_id: &Pubkey,
-        accounts: &mut &[AccountInfo<'info>],
-        _ix_data: &[u8],
-        _bumps: &mut BTreeMap<String, u8>,
-        _reallocs: &mut BTreeSet<Pubkey>,
-    ) -> Result<Self> {
-        if accounts.is_empty() {
-            return Err(ErrorCode::AccountNotEnoughKeys.into());
-        }
-        let account = &accounts[0];
-        *accounts = &accounts[1..];
-        // No owner check is done here.
-        let pa = CpiAccount::try_from(account)?;
-        Ok(pa)
-    }
-}
-
-#[allow(deprecated)]
-impl<'info, T: AccountDeserialize + Clone> ToAccountMetas for CpiAccount<'info, T> {
-    fn to_account_metas(&self, is_signer: Option<bool>) -> Vec<AccountMeta> {
-        let is_signer = is_signer.unwrap_or(self.info.is_signer);
-        let meta = match self.info.is_writable {
-            false => AccountMeta::new_readonly(*self.info.key, is_signer),
-            true => AccountMeta::new(*self.info.key, is_signer),
-        };
-        vec![meta]
-    }
-}
-
-#[allow(deprecated)]
-impl<'info, T: AccountDeserialize + Clone> ToAccountInfos<'info> for CpiAccount<'info, T> {
-    fn to_account_infos(&self) -> Vec<AccountInfo<'info>> {
-        vec![self.info.clone()]
-    }
-}
-
-#[allow(deprecated)]
-impl<'info, T: AccountDeserialize + Clone> AsRef<AccountInfo<'info>> for CpiAccount<'info, T> {
-    fn as_ref(&self) -> &AccountInfo<'info> {
-        &self.info
-    }
-}
-
-#[allow(deprecated)]
-impl<'a, T: AccountDeserialize + Clone> Deref for CpiAccount<'a, T> {
-    type Target = T;
-
-    fn deref(&self) -> &Self::Target {
-        &self.account
-    }
-}
-
-#[allow(deprecated)]
-impl<'a, T: AccountDeserialize + Clone> DerefMut for CpiAccount<'a, T> {
-    fn deref_mut(&mut self) -> &mut Self::Target {
-        &mut self.account
-    }
-}
-
-#[allow(deprecated)]
-impl<'info, T: AccountDeserialize + Clone> AccountsExit<'info> for CpiAccount<'info, T> {}
-
-#[allow(deprecated)]
-impl<'info, T> From<Account<'info, T>> for CpiAccount<'info, T>
-where
-    T: AccountSerialize + AccountDeserialize + Owner + Clone,
-{
-    fn from(a: Account<'info, T>) -> Self {
-        Self::new(a.to_account_info(), Box::new(a.into_inner()))
-    }
-}
-
-#[allow(deprecated)]
-impl<'info, T: AccountDeserialize + Clone> Key for CpiAccount<'info, T> {
-    fn key(&self) -> Pubkey {
-        *self.info.key
-    }
-}

+ 0 - 231
lang/src/accounts/loader.rs

@@ -1,231 +0,0 @@
-use crate::bpf_writer::BpfWriter;
-use crate::error::{Error, ErrorCode};
-use crate::{
-    Accounts, AccountsClose, AccountsExit, Key, Result, ToAccountInfo, ToAccountInfos,
-    ToAccountMetas, ZeroCopy,
-};
-use arrayref::array_ref;
-use solana_program::account_info::AccountInfo;
-use solana_program::instruction::AccountMeta;
-use solana_program::pubkey::Pubkey;
-use std::cell::{Ref, RefMut};
-use std::collections::{BTreeMap, BTreeSet};
-use std::fmt;
-use std::io::Write;
-use std::marker::PhantomData;
-use std::ops::DerefMut;
-
-/// Account loader facilitating on demand zero copy deserialization.
-/// Note that using accounts in this way is distinctly different from using,
-/// for example, the [`Account`](./struct.Account.html). Namely,
-/// one must call `load`, `load_mut`, or `load_init`, before reading or writing
-/// to the account. For more details on zero-copy-deserialization, see the
-/// [`account`](./attr.account.html) attribute.
-///
-/// When using it's important to be mindful of any calls to `load` so as not to
-/// induce a `RefCell` panic, especially when sharing accounts across CPI
-/// boundaries. When in doubt, one should make sure all refs resulting from a
-/// call to `load` are dropped before CPI.
-#[deprecated(since = "0.18.0", note = "Please use AccountLoader instead")]
-pub struct Loader<'info, T: ZeroCopy> {
-    acc_info: AccountInfo<'info>,
-    phantom: PhantomData<&'info T>,
-}
-
-#[allow(deprecated)]
-impl<'info, T: ZeroCopy + fmt::Debug> fmt::Debug for Loader<'info, T> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_struct("Loader")
-            .field("acc_info", &self.acc_info)
-            .field("phantom", &self.phantom)
-            .finish()
-    }
-}
-
-#[allow(deprecated)]
-impl<'info, T: ZeroCopy> Loader<'info, T> {
-    fn new(acc_info: AccountInfo<'info>) -> Loader<'info, T> {
-        Self {
-            acc_info,
-            phantom: PhantomData,
-        }
-    }
-
-    /// Constructs a new `Loader` from a previously initialized account.
-    #[inline(never)]
-    #[allow(deprecated)]
-    pub fn try_from(
-        program_id: &Pubkey,
-        acc_info: &AccountInfo<'info>,
-    ) -> Result<Loader<'info, T>> {
-        if acc_info.owner != program_id {
-            return Err(Error::from(ErrorCode::AccountOwnedByWrongProgram)
-                .with_pubkeys((*acc_info.owner, *program_id)));
-        }
-        let data: &[u8] = &acc_info.try_borrow_data()?;
-        if data.len() < T::discriminator().len() {
-            return Err(ErrorCode::AccountDiscriminatorNotFound.into());
-        }
-        // Discriminator must match.
-        let disc_bytes = array_ref![data, 0, 8];
-        if disc_bytes != &T::discriminator() {
-            return Err(ErrorCode::AccountDiscriminatorMismatch.into());
-        }
-
-        Ok(Loader::new(acc_info.clone()))
-    }
-
-    /// Constructs a new `Loader` from an uninitialized account.
-    #[allow(deprecated)]
-    #[inline(never)]
-    pub fn try_from_unchecked(
-        program_id: &Pubkey,
-        acc_info: &AccountInfo<'info>,
-    ) -> Result<Loader<'info, T>> {
-        if acc_info.owner != program_id {
-            return Err(Error::from(ErrorCode::AccountOwnedByWrongProgram)
-                .with_pubkeys((*acc_info.owner, *program_id)));
-        }
-        Ok(Loader::new(acc_info.clone()))
-    }
-
-    /// Returns a Ref to the account data structure for reading.
-    #[allow(deprecated)]
-    pub fn load(&self) -> Result<Ref<T>> {
-        let data = self.acc_info.try_borrow_data()?;
-        if data.len() < T::discriminator().len() {
-            return Err(ErrorCode::AccountDiscriminatorNotFound.into());
-        }
-
-        let disc_bytes = array_ref![data, 0, 8];
-        if disc_bytes != &T::discriminator() {
-            return Err(ErrorCode::AccountDiscriminatorMismatch.into());
-        }
-
-        Ok(Ref::map(data, |data| bytemuck::from_bytes(&data[8..])))
-    }
-
-    /// Returns a `RefMut` to the account data structure for reading or writing.
-    #[allow(deprecated)]
-    pub fn load_mut(&self) -> Result<RefMut<T>> {
-        // AccountInfo api allows you to borrow mut even if the account isn't
-        // writable, so add this check for a better dev experience.
-        if !self.acc_info.is_writable {
-            return Err(ErrorCode::AccountNotMutable.into());
-        }
-
-        let data = self.acc_info.try_borrow_mut_data()?;
-        if data.len() < T::discriminator().len() {
-            return Err(ErrorCode::AccountDiscriminatorNotFound.into());
-        }
-
-        let disc_bytes = array_ref![data, 0, 8];
-        if disc_bytes != &T::discriminator() {
-            return Err(ErrorCode::AccountDiscriminatorMismatch.into());
-        }
-
-        Ok(RefMut::map(data, |data| {
-            bytemuck::from_bytes_mut(&mut data.deref_mut()[8..])
-        }))
-    }
-
-    /// Returns a `RefMut` to the account data structure for reading or writing.
-    /// Should only be called once, when the account is being initialized.
-    #[allow(deprecated)]
-    pub fn load_init(&self) -> Result<RefMut<T>> {
-        // AccountInfo api allows you to borrow mut even if the account isn't
-        // writable, so add this check for a better dev experience.
-        if !self.acc_info.is_writable {
-            return Err(ErrorCode::AccountNotMutable.into());
-        }
-
-        let data = self.acc_info.try_borrow_mut_data()?;
-
-        // The discriminator should be zero, since we're initializing.
-        let mut disc_bytes = [0u8; 8];
-        disc_bytes.copy_from_slice(&data[..8]);
-        let discriminator = u64::from_le_bytes(disc_bytes);
-        if discriminator != 0 {
-            return Err(ErrorCode::AccountDiscriminatorAlreadySet.into());
-        }
-
-        Ok(RefMut::map(data, |data| {
-            bytemuck::from_bytes_mut(&mut data.deref_mut()[8..])
-        }))
-    }
-}
-
-#[allow(deprecated)]
-impl<'info, T: ZeroCopy> Accounts<'info> for Loader<'info, T> {
-    #[inline(never)]
-    fn try_accounts(
-        program_id: &Pubkey,
-        accounts: &mut &[AccountInfo<'info>],
-        _ix_data: &[u8],
-        _bumps: &mut BTreeMap<String, u8>,
-        _reallocs: &mut BTreeSet<Pubkey>,
-    ) -> Result<Self> {
-        if accounts.is_empty() {
-            return Err(ErrorCode::AccountNotEnoughKeys.into());
-        }
-        let account = &accounts[0];
-        *accounts = &accounts[1..];
-        let l = Loader::try_from(program_id, account)?;
-        Ok(l)
-    }
-}
-
-#[allow(deprecated)]
-impl<'info, T: ZeroCopy> AccountsExit<'info> for Loader<'info, T> {
-    // The account *cannot* be loaded when this is called.
-    fn exit(&self, _program_id: &Pubkey) -> Result<()> {
-        // Only persist if the account is not closed.
-        if !crate::common::is_closed(&self.acc_info) {
-            let mut data = self.acc_info.try_borrow_mut_data()?;
-            let dst: &mut [u8] = &mut data;
-            let mut writer = BpfWriter::new(dst);
-            writer.write_all(&T::discriminator()).unwrap();
-        }
-        Ok(())
-    }
-}
-
-#[allow(deprecated)]
-impl<'info, T: ZeroCopy> AccountsClose<'info> for Loader<'info, T> {
-    fn close(&self, sol_destination: AccountInfo<'info>) -> Result<()> {
-        crate::common::close(self.to_account_info(), sol_destination)
-    }
-}
-
-#[allow(deprecated)]
-impl<'info, T: ZeroCopy> ToAccountMetas for Loader<'info, T> {
-    fn to_account_metas(&self, is_signer: Option<bool>) -> Vec<AccountMeta> {
-        let is_signer = is_signer.unwrap_or(self.acc_info.is_signer);
-        let meta = match self.acc_info.is_writable {
-            false => AccountMeta::new_readonly(*self.acc_info.key, is_signer),
-            true => AccountMeta::new(*self.acc_info.key, is_signer),
-        };
-        vec![meta]
-    }
-}
-
-#[allow(deprecated)]
-impl<'info, T: ZeroCopy> AsRef<AccountInfo<'info>> for Loader<'info, T> {
-    fn as_ref(&self) -> &AccountInfo<'info> {
-        &self.acc_info
-    }
-}
-
-#[allow(deprecated)]
-impl<'info, T: ZeroCopy> ToAccountInfos<'info> for Loader<'info, T> {
-    fn to_account_infos(&self) -> Vec<AccountInfo<'info>> {
-        vec![self.acc_info.clone()]
-    }
-}
-
-#[allow(deprecated)]
-impl<'info, T: ZeroCopy> Key for Loader<'info, T> {
-    fn key(&self) -> Pubkey {
-        *self.acc_info.key
-    }
-}

+ 0 - 9
lang/src/accounts/mod.rs

@@ -4,17 +4,8 @@ pub mod account;
 pub mod account_info;
 pub mod account_loader;
 pub mod boxed;
-#[doc(hidden)]
-#[allow(deprecated)]
-pub mod cpi_account;
-#[doc(hidden)]
-#[allow(deprecated)]
-pub mod loader;
 pub mod option;
 pub mod program;
-#[doc(hidden)]
-#[allow(deprecated)]
-pub mod program_account;
 pub mod signer;
 pub mod system_account;
 pub mod sysvar;

+ 0 - 192
lang/src/accounts/program_account.rs

@@ -1,192 +0,0 @@
-#[allow(deprecated)]
-use crate::accounts::cpi_account::CpiAccount;
-use crate::bpf_writer::BpfWriter;
-use crate::error::{Error, ErrorCode};
-use crate::{
-    AccountDeserialize, AccountSerialize, Accounts, AccountsClose, AccountsExit, Key, Result,
-    ToAccountInfo, ToAccountInfos, ToAccountMetas,
-};
-use solana_program::account_info::AccountInfo;
-use solana_program::instruction::AccountMeta;
-use solana_program::pubkey::Pubkey;
-use std::collections::{BTreeMap, BTreeSet};
-use std::ops::{Deref, DerefMut};
-
-/// Boxed container for a deserialized `account`. Use this to reference any
-/// account owned by the currently executing program.
-#[derive(Clone)]
-#[deprecated(since = "0.15.0", note = "Please use Account instead")]
-pub struct ProgramAccount<'info, T: AccountSerialize + AccountDeserialize + Clone> {
-    inner: Box<Inner<'info, T>>,
-}
-
-#[derive(Clone)]
-struct Inner<'info, T: AccountSerialize + AccountDeserialize + Clone> {
-    info: AccountInfo<'info>,
-    account: T,
-}
-
-#[allow(deprecated)]
-impl<'a, T: AccountSerialize + AccountDeserialize + Clone> ProgramAccount<'a, T> {
-    fn new(info: AccountInfo<'a>, account: T) -> ProgramAccount<'a, T> {
-        Self {
-            inner: Box::new(Inner { info, account }),
-        }
-    }
-
-    /// Deserializes the given `info` into a `ProgramAccount`.
-    #[inline(never)]
-    pub fn try_from(program_id: &Pubkey, info: &AccountInfo<'a>) -> Result<ProgramAccount<'a, T>> {
-        if info.owner != program_id {
-            return Err(Error::from(ErrorCode::AccountOwnedByWrongProgram)
-                .with_pubkeys((*info.owner, *program_id)));
-        }
-        let mut data: &[u8] = &info.try_borrow_data()?;
-        Ok(ProgramAccount::new(
-            info.clone(),
-            T::try_deserialize(&mut data)?,
-        ))
-    }
-
-    /// Deserializes the given `info` into a `ProgramAccount` without checking
-    /// the account discriminator. Be careful when using this and avoid it if
-    /// possible.
-    #[inline(never)]
-    pub fn try_from_unchecked(
-        program_id: &Pubkey,
-        info: &AccountInfo<'a>,
-    ) -> Result<ProgramAccount<'a, T>> {
-        if info.owner != program_id {
-            return Err(Error::from(ErrorCode::AccountOwnedByWrongProgram)
-                .with_pubkeys((*info.owner, *program_id)));
-        }
-        let mut data: &[u8] = &info.try_borrow_data()?;
-        Ok(ProgramAccount::new(
-            info.clone(),
-            T::try_deserialize_unchecked(&mut data)?,
-        ))
-    }
-
-    pub fn into_inner(self) -> T {
-        self.inner.account
-    }
-}
-
-#[allow(deprecated)]
-impl<'info, T> Accounts<'info> for ProgramAccount<'info, T>
-where
-    T: AccountSerialize + AccountDeserialize + Clone,
-{
-    #[inline(never)]
-    fn try_accounts(
-        program_id: &Pubkey,
-        accounts: &mut &[AccountInfo<'info>],
-        _ix_data: &[u8],
-        _bumps: &mut BTreeMap<String, u8>,
-        _reallocs: &mut BTreeSet<Pubkey>,
-    ) -> Result<Self> {
-        if accounts.is_empty() {
-            return Err(ErrorCode::AccountNotEnoughKeys.into());
-        }
-        let account = &accounts[0];
-        *accounts = &accounts[1..];
-        ProgramAccount::try_from(program_id, account)
-    }
-}
-
-#[allow(deprecated)]
-impl<'info, T: AccountSerialize + AccountDeserialize + Clone> AccountsExit<'info>
-    for ProgramAccount<'info, T>
-{
-    fn exit(&self, _program_id: &Pubkey) -> Result<()> {
-        // Only persist if the account is not closed.
-        if !crate::common::is_closed(&self.inner.info) {
-            let info = self.to_account_info();
-            let mut data = info.try_borrow_mut_data()?;
-            let dst: &mut [u8] = &mut data;
-            let mut writer = BpfWriter::new(dst);
-            self.inner.account.try_serialize(&mut writer)?;
-        }
-        Ok(())
-    }
-}
-
-#[allow(deprecated)]
-impl<'info, T: AccountSerialize + AccountDeserialize + Clone> AccountsClose<'info>
-    for ProgramAccount<'info, T>
-{
-    fn close(&self, sol_destination: AccountInfo<'info>) -> Result<()> {
-        crate::common::close(self.to_account_info(), sol_destination)
-    }
-}
-
-#[allow(deprecated)]
-impl<'info, T: AccountSerialize + AccountDeserialize + Clone> ToAccountMetas
-    for ProgramAccount<'info, T>
-{
-    fn to_account_metas(&self, is_signer: Option<bool>) -> Vec<AccountMeta> {
-        let is_signer = is_signer.unwrap_or(self.inner.info.is_signer);
-        let meta = match self.inner.info.is_writable {
-            false => AccountMeta::new_readonly(*self.inner.info.key, is_signer),
-            true => AccountMeta::new(*self.inner.info.key, is_signer),
-        };
-        vec![meta]
-    }
-}
-
-#[allow(deprecated)]
-impl<'info, T: AccountSerialize + AccountDeserialize + Clone> ToAccountInfos<'info>
-    for ProgramAccount<'info, T>
-{
-    fn to_account_infos(&self) -> Vec<AccountInfo<'info>> {
-        vec![self.inner.info.clone()]
-    }
-}
-
-#[allow(deprecated)]
-impl<'info, T: AccountSerialize + AccountDeserialize + Clone> AsRef<AccountInfo<'info>>
-    for ProgramAccount<'info, T>
-{
-    fn as_ref(&self) -> &AccountInfo<'info> {
-        &self.inner.info
-    }
-}
-
-#[allow(deprecated)]
-impl<'a, T: AccountSerialize + AccountDeserialize + Clone> Deref for ProgramAccount<'a, T> {
-    type Target = T;
-
-    fn deref(&self) -> &Self::Target {
-        &(self.inner).account
-    }
-}
-
-#[allow(deprecated)]
-impl<'a, T: AccountSerialize + AccountDeserialize + Clone> DerefMut for ProgramAccount<'a, T> {
-    fn deref_mut(&mut self) -> &mut Self::Target {
-        #[cfg(feature = "anchor-debug")]
-        if !self.inner.info.is_writable {
-            solana_program::msg!("The given ProgramAccount is not mutable");
-            panic!();
-        }
-
-        &mut DerefMut::deref_mut(&mut self.inner).account
-    }
-}
-
-#[allow(deprecated)]
-impl<'info, T> From<CpiAccount<'info, T>> for ProgramAccount<'info, T>
-where
-    T: AccountSerialize + AccountDeserialize + Clone,
-{
-    fn from(a: CpiAccount<'info, T>) -> Self {
-        Self::new(a.to_account_info(), Deref::deref(&a).clone())
-    }
-}
-
-#[allow(deprecated)]
-impl<'info, T: AccountSerialize + AccountDeserialize + Clone> Key for ProgramAccount<'info, T> {
-    fn key(&self) -> Pubkey {
-        *self.inner.info.key
-    }
-}

+ 0 - 4
lang/syn/src/codegen/accounts/constraints.rs

@@ -261,7 +261,6 @@ pub fn generate_constraint_has_one(
     let target = &c.join_target;
     let ident = &f.ident;
     let field = match &f.ty {
-        Ty::Loader(_) => quote! {#ident.load()?},
         Ty::AccountLoader(_) => quote! {#ident.load()?},
         _ => quote! {#ident},
     };
@@ -290,11 +289,8 @@ pub fn generate_constraint_signer(f: &Field, c: &ConstraintSigner) -> proc_macro
     let ident = &f.ident;
     let info = match f.ty {
         Ty::AccountInfo => quote! { #ident },
-        Ty::ProgramAccount(_) => quote! { #ident.to_account_info() },
         Ty::Account(_) => quote! { #ident.to_account_info() },
-        Ty::Loader(_) => quote! { #ident.to_account_info() },
         Ty::AccountLoader(_) => quote! { #ident.to_account_info() },
-        Ty::CpiAccount(_) => quote! { #ident.to_account_info() },
         _ => panic!("Invalid syntax: signer cannot be specified."),
     };
     let error = generate_custom_error(ident, &c.error, quote! { ConstraintSigner }, &None);

+ 0 - 70
lang/syn/src/lib.rs

@@ -204,9 +204,6 @@ impl AccountField {
         let qualified_ty_name = match self {
             AccountField::Field(field) => match &field.ty {
                 Ty::Account(account) => Some(parser::tts_to_string(&account.account_type_path)),
-                Ty::ProgramAccount(account) => {
-                    Some(parser::tts_to_string(&account.account_type_path))
-                }
                 _ => None,
             },
             AccountField::CompositeField(field) => Some(field.symbol.clone()),
@@ -300,8 +297,6 @@ impl Field {
         }
     }
 
-    // TODO: remove the option once `CpiAccount` is completely removed (not
-    //       just deprecated).
     // Ignores optional accounts. Optional account checks and handing should be done prior to this
     // function being called.
     pub fn from_account_info(
@@ -350,23 +345,6 @@ impl Field {
                     stream
                 }
             }
-            Ty::CpiAccount(_) => {
-                if checked {
-                    quote! {
-                        match #container_ty::try_from(&#field) {
-                            Ok(val) => val,
-                            Err(e) => return Err(e.with_account_name(#field_str))
-                        }
-                    }
-                } else {
-                    quote! {
-                        match #container_ty::try_from_unchecked(&#field) {
-                            Ok(val) => val,
-                            Err(e) => return Err(e.with_account_name(#field_str))
-                        }
-                    }
-                }
-            }
             Ty::AccountLoader(_) => {
                 if checked {
                     quote! {
@@ -406,21 +384,12 @@ impl Field {
 
     pub fn container_ty(&self) -> proc_macro2::TokenStream {
         match &self.ty {
-            Ty::ProgramAccount(_) => quote! {
-                anchor_lang::accounts::program_account::ProgramAccount
-            },
             Ty::Account(_) => quote! {
                 anchor_lang::accounts::account::Account
             },
             Ty::AccountLoader(_) => quote! {
                 anchor_lang::accounts::account_loader::AccountLoader
             },
-            Ty::Loader(_) => quote! {
-                anchor_lang::accounts::loader::Loader
-            },
-            Ty::CpiAccount(_) => quote! {
-                anchor_lang::accounts::cpi_account::CpiAccount
-            },
             Ty::Sysvar(_) => quote! { anchor_lang::accounts::sysvar::Sysvar },
             Ty::Program(_) => quote! { anchor_lang::accounts::program::Program },
             Ty::AccountInfo => quote! {},
@@ -449,12 +418,6 @@ impl Field {
             Ty::ProgramData => quote! {
                 ProgramData
             },
-            Ty::ProgramAccount(ty) => {
-                let ident = &ty.account_type_path;
-                quote! {
-                    #ident
-                }
-            }
             Ty::Account(ty) => {
                 let ident = &ty.account_type_path;
                 quote! {
@@ -467,18 +430,6 @@ impl Field {
                     #ident
                 }
             }
-            Ty::Loader(ty) => {
-                let ident = &ty.account_type_path;
-                quote! {
-                    #ident
-                }
-            }
-            Ty::CpiAccount(ty) => {
-                let ident = &ty.account_type_path;
-                quote! {
-                    #ident
-                }
-            }
             Ty::Sysvar(ty) => match ty {
                 SysvarTy::Clock => quote! {Clock},
                 SysvarTy::Rent => quote! {Rent},
@@ -516,10 +467,7 @@ pub struct CompositeField {
 pub enum Ty {
     AccountInfo,
     UncheckedAccount,
-    ProgramAccount(ProgramAccountTy),
-    Loader(LoaderTy),
     AccountLoader(AccountLoaderTy),
-    CpiAccount(CpiAccountTy),
     Sysvar(SysvarTy),
     Account(AccountTy),
     Program(ProgramTy),
@@ -542,30 +490,12 @@ pub enum SysvarTy {
     Rewards,
 }
 
-#[derive(Debug, PartialEq, Eq)]
-pub struct ProgramAccountTy {
-    // The struct type of the account.
-    pub account_type_path: TypePath,
-}
-
-#[derive(Debug, PartialEq, Eq)]
-pub struct CpiAccountTy {
-    // The struct type of the account.
-    pub account_type_path: TypePath,
-}
-
 #[derive(Debug, PartialEq, Eq)]
 pub struct AccountLoaderTy {
     // The struct type of the account.
     pub account_type_path: TypePath,
 }
 
-#[derive(Debug, PartialEq, Eq)]
-pub struct LoaderTy {
-    // The struct type of the account.
-    pub account_type_path: TypePath,
-}
-
 #[derive(Debug, PartialEq, Eq)]
 pub struct AccountTy {
     // The struct type of the account.

+ 2 - 4
lang/syn/src/parser/accounts/constraints.rs

@@ -871,14 +871,12 @@ impl<'ty> ConstraintGroupBuilder<'ty> {
     }
 
     fn add_close(&mut self, c: Context<ConstraintClose>) -> ParseResult<()> {
-        if !matches!(self.f_ty, Some(Ty::ProgramAccount(_)))
-            && !matches!(self.f_ty, Some(Ty::Account(_)))
-            && !matches!(self.f_ty, Some(Ty::Loader(_)))
+        if !matches!(self.f_ty, Some(Ty::Account(_)))
             && !matches!(self.f_ty, Some(Ty::AccountLoader(_)))
         {
             return Err(ParseError::new(
                 c.span(),
-                "close must be on an Account, ProgramAccount, or Loader",
+                "close must be on an Account, AccountLoader",
             ));
         }
         if self.mutable.is_none() {

+ 1 - 27
lang/syn/src/parser/accounts/mod.rs

@@ -283,12 +283,9 @@ pub fn parse_account_field(f: &syn::Field) -> ParseResult<AccountField> {
 fn is_field_primitive(f: &syn::Field) -> ParseResult<bool> {
     let r = matches!(
         ident_string(f)?.0.as_str(),
-        "ProgramAccount"
-            | "CpiAccount"
-            | "Sysvar"
+        "Sysvar"
             | "AccountInfo"
             | "UncheckedAccount"
-            | "Loader"
             | "AccountLoader"
             | "Account"
             | "Program"
@@ -302,12 +299,9 @@ fn is_field_primitive(f: &syn::Field) -> ParseResult<bool> {
 fn parse_ty(f: &syn::Field) -> ParseResult<(Ty, bool)> {
     let (ident, optional, path) = ident_string(f)?;
     let ty = match ident.as_str() {
-        "ProgramAccount" => Ty::ProgramAccount(parse_program_account(&path)?),
-        "CpiAccount" => Ty::CpiAccount(parse_cpi_account(&path)?),
         "Sysvar" => Ty::Sysvar(parse_sysvar(&path)?),
         "AccountInfo" => Ty::AccountInfo,
         "UncheckedAccount" => Ty::UncheckedAccount,
-        "Loader" => Ty::Loader(parse_program_account_zero_copy(&path)?),
         "AccountLoader" => Ty::AccountLoader(parse_program_account_loader(&path)?),
         "Account" => Ty::Account(parse_account_ty(&path)?),
         "Program" => Ty::Program(parse_program_ty(&path)?),
@@ -376,26 +370,6 @@ fn ident_string(f: &syn::Field) -> ParseResult<(String, bool, Path)> {
     Ok((segments.ident.to_string(), optional, path))
 }
 
-fn parse_cpi_account(path: &syn::Path) -> ParseResult<CpiAccountTy> {
-    let account_ident = parse_account(path)?;
-    Ok(CpiAccountTy {
-        account_type_path: account_ident,
-    })
-}
-
-fn parse_program_account(path: &syn::Path) -> ParseResult<ProgramAccountTy> {
-    let account_ident = parse_account(path)?;
-    Ok(ProgramAccountTy {
-        account_type_path: account_ident,
-    })
-}
-
-fn parse_program_account_zero_copy(path: &syn::Path) -> ParseResult<LoaderTy> {
-    let account_ident = parse_account(path)?;
-    Ok(LoaderTy {
-        account_type_path: account_ident,
-    })
-}
 fn parse_program_account_loader(path: &syn::Path) -> ParseResult<AccountLoaderTy> {
     let account_ident = parse_account(path)?;
     Ok(AccountLoaderTy {

+ 2 - 3
tests/chat/programs/chat/src/lib.rs

@@ -1,6 +1,5 @@
 //! A simple chat program using a ring buffer to store messages.
 
-use anchor_lang::accounts::loader::Loader;
 use anchor_lang::prelude::*;
 
 declare_id!("Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS");
@@ -57,7 +56,7 @@ pub struct CreateUser<'info> {
 #[derive(Accounts)]
 pub struct CreateChatRoom<'info> {
     #[account(zero)]
-    chat_room: Loader<'info, ChatRoom>,
+    chat_room: AccountLoader<'info, ChatRoom>,
 }
 
 #[derive(Accounts)]
@@ -70,7 +69,7 @@ pub struct SendMessage<'info> {
     user: Account<'info, User>,
     authority: Signer<'info>,
     #[account(mut)]
-    chat_room: Loader<'info, ChatRoom>,
+    chat_room: AccountLoader<'info, ChatRoom>,
 }
 
 #[account]

+ 1 - 2
tests/misc/programs/misc-optional/src/context.rs

@@ -1,5 +1,4 @@
 use crate::account::*;
-use anchor_lang::accounts::loader::Loader;
 use anchor_lang::prelude::*;
 use anchor_spl::associated_token::AssociatedToken;
 use anchor_spl::token::{Mint, Token, TokenAccount};
@@ -218,7 +217,7 @@ pub struct TestInit<'info> {
 #[derive(Accounts)]
 pub struct TestInitZeroCopy<'info> {
     #[account(init, payer = payer, space = DataZeroCopy::LEN + 8)]
-    pub data: Option<Loader<'info, DataZeroCopy>>,
+    pub data: Option<AccountLoader<'info, DataZeroCopy>>,
     #[account(mut)]
     pub payer: Option<Signer<'info>>,
     pub system_program: Option<Program<'info, System>>,

+ 1 - 2
tests/misc/programs/misc/src/context.rs

@@ -1,5 +1,4 @@
 use crate::account::*;
-use anchor_lang::accounts::loader::Loader;
 use anchor_lang::prelude::*;
 use anchor_spl::associated_token::AssociatedToken;
 use anchor_spl::token::{Mint, Token, TokenAccount};
@@ -215,7 +214,7 @@ pub struct TestInit<'info> {
 #[derive(Accounts)]
 pub struct TestInitZeroCopy<'info> {
     #[account(init, payer = payer, space = DataZeroCopy::LEN + 8)]
-    pub data: Loader<'info, DataZeroCopy>,
+    pub data: AccountLoader<'info, DataZeroCopy>,
     #[account(mut)]
     pub payer: Signer<'info>,
     pub system_program: Program<'info, System>,

+ 2 - 2
tests/misc/programs/misc/src/lib.rs

@@ -66,7 +66,7 @@ pub mod misc {
         Ok(())
     }
 
-    pub fn test_input_enum(ctx: Context<TestSimulate>, data: TestEnum) -> Result<()> {
+    pub fn test_input_enum(_ctx: Context<TestSimulate>, data: TestEnum) -> Result<()> {
         emit!(E7 { data: data });
         Ok(())
     }
@@ -247,7 +247,7 @@ pub mod misc {
         Ok(())
     }
 
-    pub fn init_with_space(_ctx: Context<InitWithSpace>, data: u16) -> Result<()> {
+    pub fn init_with_space(_ctx: Context<InitWithSpace>, _data: u16) -> Result<()> {
         Ok(())
     }
 

+ 8 - 9
tests/multisig/programs/multisig/src/lib.rs

@@ -17,7 +17,6 @@
 //! the `execute_transaction`, once enough (i.e. `threshold`) of the owners have
 //! signed.
 
-use anchor_lang::accounts::program_account::ProgramAccount;
 use anchor_lang::prelude::*;
 use anchor_lang::solana_program;
 use anchor_lang::solana_program::instruction::Instruction;
@@ -168,23 +167,23 @@ pub mod multisig {
 #[derive(Accounts)]
 pub struct CreateMultisig<'info> {
     #[account(zero)]
-    multisig: ProgramAccount<'info, Multisig>,
+    multisig: Account<'info, Multisig>,
 }
 
 #[derive(Accounts)]
 pub struct CreateTransaction<'info> {
-    multisig: ProgramAccount<'info, Multisig>,
+    multisig: Account<'info, Multisig>,
     #[account(zero)]
-    transaction: ProgramAccount<'info, Transaction>,
+    transaction: Account<'info, Transaction>,
     // One of the owners. Checked in the handler.
     proposer: Signer<'info>,
 }
 
 #[derive(Accounts)]
 pub struct Approve<'info> {
-    multisig: ProgramAccount<'info, Multisig>,
+    multisig: Account<'info, Multisig>,
     #[account(mut, has_one = multisig)]
-    transaction: ProgramAccount<'info, Transaction>,
+    transaction: Account<'info, Transaction>,
     // One of the multisig owners. Checked in the handler.
     owner: Signer<'info>,
 }
@@ -192,7 +191,7 @@ pub struct Approve<'info> {
 #[derive(Accounts)]
 pub struct Auth<'info> {
     #[account(mut)]
-    multisig: ProgramAccount<'info, Multisig>,
+    multisig: Account<'info, Multisig>,
     #[account(
         signer,
         seeds = [multisig.to_account_info().key.as_ref()],
@@ -203,14 +202,14 @@ pub struct Auth<'info> {
 
 #[derive(Accounts)]
 pub struct ExecuteTransaction<'info> {
-    multisig: ProgramAccount<'info, Multisig>,
+    multisig: Account<'info, Multisig>,
     #[account(
         seeds = [multisig.to_account_info().key.as_ref()],
         bump = multisig.nonce,
     )]
     multisig_signer: AccountInfo<'info>,
     #[account(mut, has_one = multisig)]
-    transaction: ProgramAccount<'info, Transaction>,
+    transaction: Account<'info, Transaction>,
 }
 
 #[account]