Skip to content

Commit

Permalink
sdk: evict unchecked_div_by_const
Browse files Browse the repository at this point in the history
  • Loading branch information
buffalojoec committed Dec 5, 2024
1 parent 744db01 commit 8820955
Show file tree
Hide file tree
Showing 8 changed files with 177 additions and 134 deletions.
5 changes: 5 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ members = [
"sdk/transaction",
"sdk/transaction-context",
"sdk/transaction-error",
"sdk/unchecked-div-by-const",
"send-transaction-service",
"stake-accounts",
"storage-bigtable",
Expand Down Expand Up @@ -585,6 +586,7 @@ solana-transaction-metrics-tracker = { path = "transaction-metrics-tracker", ver
solana-turbine = { path = "turbine", version = "=2.2.0" }
solana-type-overrides = { path = "type-overrides", version = "=2.2.0" }
solana-udp-client = { path = "udp-client", version = "=2.2.0" }
solana-unchecked-div-by-const = { path = "sdk/unchecked-div-by-const", version = "=2.2.0" }
solana-version = { path = "version", version = "=2.2.0" }
solana-vote = { path = "vote", version = "=2.2.0" }
solana-vote-program = { path = "programs/vote", version = "=2.2.0" }
Expand Down
5 changes: 5 additions & 0 deletions programs/sbf/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions sdk/program/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ solana-stable-layout = { workspace = true }
solana-system-interface = { workspace = true, features = ["bincode"] }
solana-sysvar = { workspace = true, features = ["bincode", "bytemuck"] }
solana-sysvar-id = { workspace = true }
solana-unchecked-div-by-const = { workspace = true }
thiserror = { workspace = true }

# This is currently needed to build on-chain programs reliably.
Expand Down
139 changes: 5 additions & 134 deletions sdk/program/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -622,122 +622,11 @@ extern crate serde_derive;
#[cfg(feature = "frozen-abi")]
extern crate solana_frozen_abi_macro;

/// Convenience macro for doing integer division where the operation'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
///
/// # Examples
///
/// 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::arithmetic_side_effects)]
let quotient = $num / $den;
quotient
}};
}
#[deprecated(
since = "2.2.0",
note = "Use `solana-unchecked-div-by-const` crate instead"
)]
pub use solana_unchecked_div_by_const::unchecked_div_by_const;

// This module is purposefully listed after all other exports: because of an
// interaction within rustdoc between the reexports inside this module of
Expand All @@ -747,21 +636,3 @@ macro_rules! unchecked_div_by_const {
// `solana_sdk`.
#[cfg(not(target_os = "solana"))]
pub mod example_mocks;

#[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);
}
}
18 changes: 18 additions & 0 deletions sdk/unchecked-div-by-const/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[package]
name = "solana-unchecked-div-by-const"
description = "Compile-time-safe division."
documentation = "https://docs.rs/solana-rent"
version = { workspace = true }
authors = { workspace = true }
repository = { workspace = true }
homepage = { workspace = true }
license = { workspace = true }
edition = { workspace = true }

[dependencies]

[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

[lints]
workspace = true
136 changes: 136 additions & 0 deletions sdk/unchecked-div-by-const/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
//! Compile-time-safe division.
/// Convenience macro for doing integer division where the operation'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
///
/// # Examples
///
/// Literal denominator div-by-zero fails:
///
/// ```compile_fail
/// # use solana_unchecked_div_by_const::unchecked_div_by_const;
/// # fn main() {
/// let _ = unchecked_div_by_const!(10, 0);
/// # }
/// ```
///
/// Const denominator div-by-zero fails:
///
/// ```compile_fail
/// # use solana_unchecked_div_by_const::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_unchecked_div_by_const::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_unchecked_div_by_const::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_unchecked_div_by_const::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_unchecked_div_by_const::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_unchecked_div_by_const::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_unchecked_div_by_const::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_unchecked_div_by_const::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::arithmetic_side_effects)]
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);
}
}
5 changes: 5 additions & 0 deletions svm/examples/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 8820955

Please sign in to comment.