#![feature(rustc_private)]
#![allow(unstable_features)]
#![allow(clippy::useless_attribute)]
extern crate rustc_driver;
extern crate rustc_lint;
extern crate rustc_session;
pub mod lints;
mod macros;
pub mod shared;
pub use paste;
pub const PINA_LINTS_VERSION: &str = "1";
pub const DYLINT_VERSION: &str = "0.1.0";
pub static LINTS: &[&rustc_lint::Lint] = &[
lints::deny_account_borrows_across_cpi::DENY_ACCOUNT_BORROWS_ACROSS_CPI,
lints::deny_heap_allocations_in_onchain_instruction_handlers::DENY_HEAP_ALLOCATIONS_IN_ONCHAIN_INSTRUCTION_HANDLERS,
lints::require_associated_token_address_before_ata_cast::REQUIRE_ASSOCIATED_TOKEN_ADDRESS_BEFORE_ATA_CAST,
lints::require_bounded_remaining_accounts::REQUIRE_BOUNDED_REMAINING_ACCOUNTS,
lints::require_canonical_bump_before_pda_write::REQUIRE_CANONICAL_BUMP_BEFORE_PDA_WRITE,
lints::require_canonical_instruction_dispatch_for_idl::REQUIRE_CANONICAL_INSTRUCTION_DISPATCH_FOR_IDL,
lints::require_checked_asset_arithmetic::REQUIRE_CHECKED_ASSET_ARITHMETIC,
lints::require_consistent_token_program::REQUIRE_CONSISTENT_TOKEN_PROGRAM,
lints::require_empty_before_init::REQUIRE_EMPTY_BEFORE_INIT,
lints::require_explicit_discriminators_and_seed_namespaces::REQUIRE_EXPLICIT_DISCRIMINATORS_AND_SEED_NAMESPACES,
lints::require_explicit_token_2022_extension_policy::REQUIRE_EXPLICIT_TOKEN_2022_EXTENSION_POLICY,
lints::require_idl_root_to_define_one_program_id::REQUIRE_IDL_ROOT_TO_DEFINE_ONE_PROGRAM_ID,
lints::require_owner_before_token_cast::REQUIRE_OWNER_BEFORE_TOKEN_CAST,
lints::require_post_cpi_balance_reload::REQUIRE_POST_CPI_BALANCE_RELOAD,
lints::require_program_check_before_cpi::REQUIRE_PROGRAM_CHECK_BEFORE_CPI,
lints::require_program_owned_before_lamport_mutation::REQUIRE_PROGRAM_OWNED_BEFORE_LAMPORT_MUTATION,
lints::require_reason_for_duplicate_remaining_accounts::REQUIRE_REASON_FOR_DUPLICATE_REMAINING_ACCOUNTS,
lints::require_sysvar_assert_before_sysvar_use::REQUIRE_SYSVAR_ASSERT_BEFORE_SYSVAR_USE,
lints::require_type_assert_before_zero_copy_cast::REQUIRE_TYPE_ASSERT_BEFORE_ZERO_COPY_CAST,
lints::require_writable_before_account_resize::REQUIRE_WRITABLE_BEFORE_ACCOUNT_RESIZE,
lints::require_zeroed_before_close::REQUIRE_ZEROED_BEFORE_CLOSE,
];
pub const LINT_NAMES: &[&str] = &[
"deny_account_borrows_across_cpi",
"deny_heap_allocations_in_onchain_instruction_handlers",
"require_associated_token_address_before_ata_cast",
"require_bounded_remaining_accounts",
"require_canonical_bump_before_pda_write",
"require_canonical_instruction_dispatch_for_idl",
"require_checked_asset_arithmetic",
"require_consistent_token_program",
"require_empty_before_init",
"require_explicit_discriminators_and_seed_namespaces",
"require_explicit_token_2022_extension_policy",
"require_idl_root_to_define_one_program_id",
"require_owner_before_token_cast",
"require_post_cpi_balance_reload",
"require_program_check_before_cpi",
"require_program_owned_before_lamport_mutation",
"require_reason_for_duplicate_remaining_accounts",
"require_sysvar_assert_before_sysvar_use",
"require_type_assert_before_zero_copy_cast",
"require_writable_before_account_resize",
"require_zeroed_before_close",
];
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct LintInfo {
pub name: &'static str,
pub default_level: &'static str,
pub desc: &'static str,
}
#[must_use = "iterate the catalog to inspect the registered lints"]
pub fn catalog() -> impl Iterator<Item = LintInfo> {
LINT_NAMES.iter().zip(LINTS).map(|(name, lint)| {
LintInfo {
name,
default_level: lint.default_level.as_str(),
desc: lint.desc,
}
})
}
pub fn register_all_lints(_sess: &rustc_session::Session, lint_store: &mut rustc_lint::LintStore) {
for name in LINT_NAMES {
register_one_lint(name, lint_store);
}
}
pub fn register_selected_lints(
_sess: &rustc_session::Session,
lint_store: &mut rustc_lint::LintStore,
names: &[&str],
) {
for name in names {
register_one_lint(name, lint_store);
}
}
fn register_one_lint(name: &str, lint_store: &mut rustc_lint::LintStore) {
match name {
"deny_account_borrows_across_cpi" => {
lint_store.register_lints(&[
lints::deny_account_borrows_across_cpi::DENY_ACCOUNT_BORROWS_ACROSS_CPI,
]);
lint_store.register_late_pass(|_| {
Box::new(lints::deny_account_borrows_across_cpi::DenyAccountBorrowsAcrossCpi)
});
}
"deny_heap_allocations_in_onchain_instruction_handlers" => {
lint_store.register_lints(&[
lints::deny_heap_allocations_in_onchain_instruction_handlers::DENY_HEAP_ALLOCATIONS_IN_ONCHAIN_INSTRUCTION_HANDLERS,
]);
lint_store.register_late_pass(|_| {
Box::new(
lints::deny_heap_allocations_in_onchain_instruction_handlers::DenyHeapAllocationsInOnchainInstructionHandlers,
)
});
}
"require_associated_token_address_before_ata_cast" => {
lint_store.register_lints(&[
lints::require_associated_token_address_before_ata_cast::REQUIRE_ASSOCIATED_TOKEN_ADDRESS_BEFORE_ATA_CAST,
]);
lint_store.register_late_pass(|_| {
Box::new(
lints::require_associated_token_address_before_ata_cast::RequireAssociatedTokenAddressBeforeAtaCast,
)
});
}
"require_bounded_remaining_accounts" => {
lint_store.register_lints(&[
lints::require_bounded_remaining_accounts::REQUIRE_BOUNDED_REMAINING_ACCOUNTS,
]);
lint_store.register_late_pass(|_| {
Box::new(lints::require_bounded_remaining_accounts::RequireBoundedRemainingAccounts)
});
}
"require_canonical_bump_before_pda_write" => {
lint_store.register_lints(&[
lints::require_canonical_bump_before_pda_write::REQUIRE_CANONICAL_BUMP_BEFORE_PDA_WRITE,
]);
lint_store.register_late_pass(|_| {
Box::new(
lints::require_canonical_bump_before_pda_write::RequireCanonicalBumpBeforePdaWrite,
)
});
}
"require_canonical_instruction_dispatch_for_idl" => {
lint_store.register_lints(&[
lints::require_canonical_instruction_dispatch_for_idl::REQUIRE_CANONICAL_INSTRUCTION_DISPATCH_FOR_IDL,
]);
lint_store.register_late_pass(|_| {
Box::new(
lints::require_canonical_instruction_dispatch_for_idl::RequireCanonicalInstructionDispatchForIdl,
)
});
}
"require_checked_asset_arithmetic" => {
lint_store.register_lints(&[
lints::require_checked_asset_arithmetic::REQUIRE_CHECKED_ASSET_ARITHMETIC,
]);
lint_store.register_late_pass(|_| {
Box::new(lints::require_checked_asset_arithmetic::RequireCheckedAssetArithmetic)
});
}
"require_consistent_token_program" => {
lint_store.register_lints(&[
lints::require_consistent_token_program::REQUIRE_CONSISTENT_TOKEN_PROGRAM,
]);
lint_store.register_late_pass(|_| {
Box::new(lints::require_consistent_token_program::RequireConsistentTokenProgram)
});
}
"require_empty_before_init" => {
lint_store
.register_lints(&[lints::require_empty_before_init::REQUIRE_EMPTY_BEFORE_INIT]);
lint_store.register_late_pass(|_| {
Box::new(lints::require_empty_before_init::RequireEmptyBeforeInit)
});
}
"require_explicit_discriminators_and_seed_namespaces" => {
lint_store.register_lints(&[
lints::require_explicit_discriminators_and_seed_namespaces::REQUIRE_EXPLICIT_DISCRIMINATORS_AND_SEED_NAMESPACES,
]);
lint_store.register_late_pass(|_| {
Box::new(
lints::require_explicit_discriminators_and_seed_namespaces::RequireExplicitDiscriminatorsAndSeedNamespaces,
)
});
}
"require_explicit_token_2022_extension_policy" => {
lint_store.register_lints(&[
lints::require_explicit_token_2022_extension_policy::REQUIRE_EXPLICIT_TOKEN_2022_EXTENSION_POLICY,
]);
lint_store.register_late_pass(|_| {
Box::new(
lints::require_explicit_token_2022_extension_policy::RequireExplicitToken2022ExtensionPolicy,
)
});
}
"require_idl_root_to_define_one_program_id" => {
lint_store.register_lints(&[
lints::require_idl_root_to_define_one_program_id::REQUIRE_IDL_ROOT_TO_DEFINE_ONE_PROGRAM_ID,
]);
lint_store.register_late_pass(|_| {
Box::new(
lints::require_idl_root_to_define_one_program_id::RequireIdlRootToDefineOneProgramId,
)
});
}
"require_owner_before_token_cast" => {
lint_store.register_lints(&[
lints::require_owner_before_token_cast::REQUIRE_OWNER_BEFORE_TOKEN_CAST,
]);
lint_store.register_late_pass(|_| {
Box::new(lints::require_owner_before_token_cast::RequireOwnerBeforeTokenCast)
});
}
"require_post_cpi_balance_reload" => {
lint_store.register_lints(&[
lints::require_post_cpi_balance_reload::REQUIRE_POST_CPI_BALANCE_RELOAD,
]);
lint_store.register_late_pass(|_| {
Box::new(lints::require_post_cpi_balance_reload::RequirePostCpiBalanceReload)
});
}
"require_program_check_before_cpi" => {
lint_store.register_lints(&[
lints::require_program_check_before_cpi::REQUIRE_PROGRAM_CHECK_BEFORE_CPI,
]);
lint_store.register_late_pass(|_| {
Box::new(lints::require_program_check_before_cpi::RequireProgramCheckBeforeCpi)
});
}
"require_program_owned_before_lamport_mutation" => {
lint_store.register_lints(&[
lints::require_program_owned_before_lamport_mutation::REQUIRE_PROGRAM_OWNED_BEFORE_LAMPORT_MUTATION,
]);
lint_store.register_late_pass(|_| {
Box::new(
lints::require_program_owned_before_lamport_mutation::RequireProgramOwnedBeforeLamportMutation,
)
});
}
"require_reason_for_duplicate_remaining_accounts" => {
lint_store.register_lints(&[
lints::require_reason_for_duplicate_remaining_accounts::REQUIRE_REASON_FOR_DUPLICATE_REMAINING_ACCOUNTS,
]);
lint_store.register_pre_expansion_pass(|| {
Box::new(
lints::require_reason_for_duplicate_remaining_accounts::RequireReasonForDuplicateRemainingAccounts,
)
});
}
"require_sysvar_assert_before_sysvar_use" => {
lint_store.register_lints(&[
lints::require_sysvar_assert_before_sysvar_use::REQUIRE_SYSVAR_ASSERT_BEFORE_SYSVAR_USE,
]);
lint_store.register_late_pass(|_| {
Box::new(
lints::require_sysvar_assert_before_sysvar_use::RequireSysvarAssertBeforeSysvarUse,
)
});
}
"require_type_assert_before_zero_copy_cast" => {
lint_store.register_lints(&[
lints::require_type_assert_before_zero_copy_cast::REQUIRE_TYPE_ASSERT_BEFORE_ZERO_COPY_CAST,
]);
lint_store.register_late_pass(|_| {
Box::new(
lints::require_type_assert_before_zero_copy_cast::RequireTypeAssertBeforeZeroCopyCast,
)
});
}
"require_writable_before_account_resize" => {
lint_store.register_lints(&[
lints::require_writable_before_account_resize::REQUIRE_WRITABLE_BEFORE_ACCOUNT_RESIZE,
]);
lint_store.register_late_pass(|_| {
Box::new(
lints::require_writable_before_account_resize::RequireWritableBeforeAccountResize,
)
});
}
"require_zeroed_before_close" => {
lint_store
.register_lints(&[lints::require_zeroed_before_close::REQUIRE_ZEROED_BEFORE_CLOSE]);
lint_store.register_late_pass(|_| {
Box::new(lints::require_zeroed_before_close::RequireZeroedBeforeClose)
});
}
_ => {}
}
}
#[unsafe(no_mangle)]
pub fn register_lints(sess: &rustc_session::Session, lint_store: &mut rustc_lint::LintStore) {
register_all_lints(sess, lint_store);
}
#[unsafe(no_mangle)]
pub extern "C" fn pina_lints_version() -> *mut std::os::raw::c_char {
std::ffi::CString::new(PINA_LINTS_VERSION)
.unwrap_or_else(|error| panic!("protocol version contains no interior NUL bytes: {error}"))
.into_raw()
}
#[unsafe(no_mangle)]
pub extern "C" fn dylint_version() -> *mut std::os::raw::c_char {
std::ffi::CString::new(DYLINT_VERSION)
.unwrap_or_else(|error| panic!("protocol version contains no interior NUL bytes: {error}"))
.into_raw()
}