From 4072098f1758e6b7c6a03163eb1cae6a99ba56ec Mon Sep 17 00:00:00 2001 From: Joe Richey Date: Thu, 9 Mar 2023 15:02:28 -0800 Subject: [PATCH] Move __getrandom_custom definition into an unnamed block This supersedes #341, and makes the following changes - All the code for implementing `__getrandom_custom` is now in an **named** `const` block (unnamed consts require Rust 1.37) - I found this approch [here](https://internals.rust-lang.org/t/anonymous-modules/15441) - Nothing inside the block can be referenced outside of it - `__getrandom_custom` is marked `unsafe` - It can't be accessed externally, but is "logically" unsafe as it dereferences raw pointers - The type of the function is moved to a typedef, so we can check that the defined type matches that of `getrandom:getrandom`. - Use `::core::result::Result` instead of `Result` - Similar to use use of `from_raw_parts_mut` this prevents compilation errors if `Result` is redefined. Signed-off-by: Joe Richey --- src/custom.rs | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/src/custom.rs b/src/custom.rs index 35771f15..76445ccf 100644 --- a/src/custom.rs +++ b/src/custom.rs @@ -76,16 +76,22 @@ use core::{mem::MaybeUninit, num::NonZeroU32}; #[cfg_attr(docsrs, doc(cfg(feature = "custom")))] macro_rules! register_custom_getrandom { ($path:path) => { - // We use an extern "C" function to get the guarantees of a stable ABI. - #[no_mangle] - extern "C" fn __getrandom_custom(dest: *mut u8, len: usize) -> u32 { - let f: fn(&mut [u8]) -> Result<(), $crate::Error> = $path; - let slice = unsafe { ::core::slice::from_raw_parts_mut(dest, len) }; - match f(slice) { - Ok(()) => 0, - Err(e) => e.code().get(), + // TODO(MSRV 1.37): change to unnamed block + const __getrandom_internal: () = { + // We use an extern "C" function to get the guarantees of a stable ABI. + #[no_mangle] + unsafe extern "C" fn __getrandom_custom(dest: *mut u8, len: usize) -> u32 { + // Make sure the passed function has the type of getrandom::getrandom + type F = fn(&mut [u8]) -> ::core::result::Result<(), $crate::Error>; + let _: F = $crate::getrandom; + let f: F = $path; + let slice = ::core::slice::from_raw_parts_mut(dest, len); + match f(slice) { + Ok(()) => 0, + Err(e) => e.code().get(), + } } - } + }; }; }