1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198
#![cfg_attr(RUSTC_WITH_SPECIALIZATION, feature(specialization))] #![cfg_attr(RUSTC_NEEDS_PROC_MACRO_HYGIENE, feature(proc_macro_hygiene))] #![allow(clippy::integer_arithmetic)] // Allows macro expansion of `use ::solana_program::*` to work within this crate extern crate self as solana_program; pub mod account_info; pub mod borsh; pub mod bpf_loader; pub mod bpf_loader_deprecated; pub mod bpf_loader_upgradeable; pub mod clock; pub mod decode_error; pub mod entrypoint; pub mod entrypoint_deprecated; pub mod epoch_schedule; pub mod feature; pub mod fee_calculator; pub mod hash; pub mod incinerator; pub mod instruction; pub mod loader_instruction; pub mod loader_upgradeable_instruction; pub mod log; pub mod message; pub mod native_token; pub mod nonce; pub mod program; pub mod program_error; pub mod program_option; pub mod program_pack; pub mod program_stubs; pub mod pubkey; pub mod rent; pub mod sanitize; pub mod secp256k1_program; pub mod serialize_utils; pub mod short_vec; pub mod slot_hashes; pub mod slot_history; pub mod stake_history; pub mod system_instruction; pub mod system_program; pub mod sysvar; /// Convenience macro to declare a static public key and functions to interact with it /// /// Input: a single literal base58 string representation of a program's id /// /// # Example /// /// ``` /// # // wrapper is used so that the macro invocation occurs in the item position /// # // rather than in the statement position which isn't allowed. /// use std::str::FromStr; /// use solana_program::{declare_id, pubkey::Pubkey}; /// /// # mod item_wrapper { /// # use solana_program::declare_id; /// declare_id!("My11111111111111111111111111111111111111111"); /// # } /// # use item_wrapper::id; /// /// let my_id = Pubkey::from_str("My11111111111111111111111111111111111111111").unwrap(); /// assert_eq!(id(), my_id); /// ``` pub use solana_sdk_macro::program_declare_id as declare_id; #[macro_use] extern crate serde_derive; #[macro_use] extern crate solana_frozen_abi_macro; /// Convenience macro for doing integer division where the opersation's safety /// can be checked at compile-time /// /// Since `unchecked_div_by_const!()` is supposed to fail at compile-time, abuse /// doctests to cover failure modes /// Literal denominator div-by-zero fails /// ```compile_fail /// # use solana_program::unchecked_div_by_const; /// # fn main() { /// # let _ = unchecked_div_by_const!(10, 0); /// # } /// ``` /// # /// # Const denominator div-by-zero fails /// ```compile_fail /// # use solana_program::unchecked_div_by_const; /// # fn main() { /// # const D: u64 = 0; /// # let _ = unchecked_div_by_const!(10, D); /// # } /// ``` /// # /// # Non-const denominator fails /// ```compile_fail /// # use solana_program::unchecked_div_by_const; /// # fn main() { /// # let d = 0; /// # let _ = unchecked_div_by_const!(10, d); /// # } /// ``` /// # /// Literal denominator div-by-zero fails /// ```compile_fail /// # use solana_program::unchecked_div_by_const; /// # fn main() { /// # const N: u64 = 10; /// # let _ = unchecked_div_by_const!(N, 0); /// # } /// ``` /// # /// # Const denominator div-by-zero fails /// ```compile_fail /// # use solana_program::unchecked_div_by_const; /// # fn main() { /// # const N: u64 = 10; /// # const D: u64 = 0; /// # let _ = unchecked_div_by_const!(N, D); /// # } /// ``` /// # /// # Non-const denominator fails /// ```compile_fail /// # use solana_program::unchecked_div_by_const; /// # fn main() { /// # const N: u64 = 10; /// # let d = 0; /// # let _ = unchecked_div_by_const!(N, d); /// # } /// ``` /// # /// Literal denominator div-by-zero fails /// ```compile_fail /// # use solana_program::unchecked_div_by_const; /// # fn main() { /// # let n = 10; /// # let _ = unchecked_div_by_const!(n, 0); /// # } /// ``` /// # /// # Const denominator div-by-zero fails /// ```compile_fail /// # use solana_program::unchecked_div_by_const; /// # fn main() { /// # let n = 10; /// # const D: u64 = 0; /// # let _ = unchecked_div_by_const!(n, D); /// # } /// ``` /// # /// # Non-const denominator fails /// ```compile_fail /// # use solana_program::unchecked_div_by_const; /// # fn main() { /// # let n = 10; /// # let d = 0; /// # let _ = unchecked_div_by_const!(n, d); /// # } /// ``` /// # #[macro_export] macro_rules! unchecked_div_by_const { ($num:expr, $den:expr) => {{ // Ensure the denominator is compile-time constant let _ = [(); ($den - $den) as usize]; // Compile-time constant integer div-by-zero passes for some reason // when invoked from a compilation unit other than that where this // macro is defined. Do an explicit zero-check for now. Sorry about the // ugly error messages! // https://users.rust-lang.org/t/unexpected-behavior-of-compile-time-integer-div-by-zero-check-in-declarative-macro/56718 let _ = [(); ($den as usize) - 1]; #[allow(clippy::integer_arithmetic)] let quotient = $num / $den; quotient }}; } #[cfg(test)] mod tests { use super::unchecked_div_by_const; #[test] fn test_unchecked_div_by_const() { const D: u64 = 2; const N: u64 = 10; let n = 10; assert_eq!(unchecked_div_by_const!(10, 2), 5); assert_eq!(unchecked_div_by_const!(N, 2), 5); assert_eq!(unchecked_div_by_const!(n, 2), 5); assert_eq!(unchecked_div_by_const!(10, D), 5); assert_eq!(unchecked_div_by_const!(N, D), 5); assert_eq!(unchecked_div_by_const!(n, D), 5); } }