From 87805c080d397b1328e7227cd7741107d225f4c3 Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Wed, 8 Jan 2020 17:37:28 +0000 Subject: [PATCH] Use getrandom directly instead of rand This works around https://github.com/rust-lang/cargo/issues/5730 for no_std crates that try to use rand. --- Cargo.toml | 4 ++-- macro/Cargo.toml | 4 ++-- macro/src/lib.rs | 35 ++++++++++++++++++++++------------- 3 files changed, 26 insertions(+), 17 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index bcfed29..0cc1cd9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "const-random" -version = "0.1.6" +version = "0.1.7" license = "MIT OR Apache-2.0" repository = "https://github.com/tkaitchuck/constrandom" documentation = "https://docs.rs/const-random" @@ -11,5 +11,5 @@ readme = "README.md" edition = "2018" [dependencies] -const-random-macro = { path = "macro", version = "0.1.6"} +const-random-macro = { path = "macro", version = "0.1.7"} proc-macro-hack = { version = "0.5" } diff --git a/macro/Cargo.toml b/macro/Cargo.toml index 429c33f..4360709 100644 --- a/macro/Cargo.toml +++ b/macro/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "const-random-macro" -version = "0.1.6" +version = "0.1.7" license = "MIT OR Apache-2.0" repository = "https://github.com/tkaitchuck/constrandom" documentation = "https://docs.rs/const-random" @@ -14,4 +14,4 @@ proc-macro = true [dependencies] proc-macro-hack = { version = "0.5" } -rand = { version = "0.7", default-features = false, features = ["getrandom"] } +getrandom = "0.1" diff --git a/macro/src/lib.rs b/macro/src/lib.rs index c5fe64b..d996933 100644 --- a/macro/src/lib.rs +++ b/macro/src/lib.rs @@ -1,24 +1,33 @@ extern crate proc_macro; +use getrandom; use proc_macro::TokenStream; use proc_macro_hack::proc_macro_hack; -use rand::rngs::OsRng; -use rand::Rng; +use std::mem; + +// Ideally we would use the proper interface for this through the rand crate, +// but due to https://github.com/rust-lang/cargo/issues/5730 this leads to +// issues for no_std crates that try to use rand themselves. So instead we skip +// rand and generate random bytes straight from the OS. +fn gen_random() -> T { + let mut out = [0u8; 16]; + getrandom::getrandom(&mut out).unwrap(); + unsafe { mem::transmute_copy(&out) } +} #[proc_macro_hack] pub fn const_random(input: TokenStream) -> TokenStream { match &input.to_string()[..] { - "u8" => format!("0x{:x}", OsRng.gen::()).parse().unwrap(), - "u16" => format!("0x{:x}", OsRng.gen::()).parse().unwrap(), - "u32" => format!("0x{:x}", OsRng.gen::()).parse().unwrap(), - "u64" => format!("0x{:x}", OsRng.gen::()).parse().unwrap(), - "u128" => format!("0x{:x}", OsRng.gen::()).parse().unwrap(), - "i8" => format!("0x{:x}", OsRng.gen::()).parse().unwrap(), - "i16" => format!("0x{:x}", OsRng.gen::()).parse().unwrap(), - "i32" => format!("0x{:x}", OsRng.gen::()).parse().unwrap(), - "i64" => format!("0x{:x}", OsRng.gen::()).parse().unwrap(), - "i128" => format!("0x{:x}", OsRng.gen::()).parse().unwrap(), + "u8" => format!("0x{:x}", gen_random::()).parse().unwrap(), + "u16" => format!("0x{:x}", gen_random::()).parse().unwrap(), + "u32" => format!("0x{:x}", gen_random::()).parse().unwrap(), + "u64" => format!("0x{:x}", gen_random::()).parse().unwrap(), + "u128" => format!("0x{:x}", gen_random::()).parse().unwrap(), + "i8" => format!("0x{:x}", gen_random::()).parse().unwrap(), + "i16" => format!("0x{:x}", gen_random::()).parse().unwrap(), + "i32" => format!("0x{:x}", gen_random::()).parse().unwrap(), + "i64" => format!("0x{:x}", gen_random::()).parse().unwrap(), + "i128" => format!("0x{:x}", gen_random::()).parse().unwrap(), _ => panic!("Invalid integer type"), } - }