Compare commits
No commits in common. "master" and "rocq_hdl" have entirely different histories.
2 changed files with 18 additions and 75 deletions
|
|
@ -2396,16 +2396,13 @@ impl ModuleBuilder {
|
|||
#[track_caller]
|
||||
pub fn extern_module_simulation_fn<
|
||||
Args: fmt::Debug + Clone + Hash + Eq + Send + Sync + 'static,
|
||||
F: Copy + Fn(Args, crate::sim::ExternModuleSimulationState) -> Fut + Send + Sync + 'static,
|
||||
Fut: IntoFuture<Output = ()> + 'static,
|
||||
>(
|
||||
&self,
|
||||
args: Args,
|
||||
f: F,
|
||||
f: fn(Args, crate::sim::ExternModuleSimulationState) -> Fut,
|
||||
) {
|
||||
// use for compile-time side-effect
|
||||
let _ = crate::sim::SimGeneratorFn::<Args, F, Fut>::ASSERT_F_IS_ZERO_SIZED;
|
||||
self.extern_module_simulation(crate::sim::SimGeneratorFn::new(args, f));
|
||||
self.extern_module_simulation(crate::sim::SimGeneratorFn { args, f });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@ use std::{
|
|||
hash::Hash,
|
||||
mem,
|
||||
pin::{Pin, pin},
|
||||
ptr,
|
||||
rc::Rc,
|
||||
sync::{Arc, Mutex, MutexGuard},
|
||||
task::Poll,
|
||||
|
|
@ -4064,48 +4065,13 @@ pub trait ExternModuleSimGenerator: Clone + Eq + Hash + Any + Send + Sync + fmt:
|
|||
fn run<'a>(&'a self, sim: ExternModuleSimulationState) -> impl IntoFuture<Output = ()> + 'a;
|
||||
}
|
||||
|
||||
/// Type requirements: `F` must be zero-sized, this guarantees that the function called
|
||||
/// by `F` is entirely determined by the type `F` and not by its value, allowing us to
|
||||
/// correctly leave `F` out of the stuff used for `Hash` and `Eq`.
|
||||
///
|
||||
/// Note we can't just use function pointers instead -- comparing them is non-deterministic
|
||||
/// since Rust will duplicate and/or merge functions, even if those functions happen to have
|
||||
/// different UB but just happen to compile to the same assembly language:
|
||||
/// <https://github.com/rust-lang/unsafe-code-guidelines/issues/589#issuecomment-3515424930>
|
||||
pub struct SimGeneratorFn<Args, F: Copy + Fn(Args, ExternModuleSimulationState) -> Fut, Fut> {
|
||||
args: Args,
|
||||
f: F,
|
||||
pub struct SimGeneratorFn<Args, Fut> {
|
||||
pub args: Args,
|
||||
pub f: fn(Args, ExternModuleSimulationState) -> Fut,
|
||||
}
|
||||
|
||||
impl<Args, F: Copy + Fn(Args, ExternModuleSimulationState) -> Fut, Fut>
|
||||
SimGeneratorFn<Args, F, Fut>
|
||||
{
|
||||
pub const ASSERT_F_IS_ZERO_SIZED: () = {
|
||||
if size_of::<F>() != 0 {
|
||||
panic!(
|
||||
"F must be zero-sized -- so it must be a closure with no captures or a function item, it can't be a function pointer"
|
||||
);
|
||||
}
|
||||
};
|
||||
pub const fn new(args: Args, f: F) -> Self {
|
||||
// use for compile-time side-effect
|
||||
let _ = Self::ASSERT_F_IS_ZERO_SIZED;
|
||||
Self { args, f }
|
||||
}
|
||||
pub const fn args(&self) -> &Args {
|
||||
&self.args
|
||||
}
|
||||
pub const fn f(&self) -> F {
|
||||
self.f
|
||||
}
|
||||
}
|
||||
|
||||
impl<Args: fmt::Debug, F: Copy + Fn(Args, ExternModuleSimulationState) -> Fut, Fut> fmt::Debug
|
||||
for SimGeneratorFn<Args, F, Fut>
|
||||
{
|
||||
impl<Args: fmt::Debug, Fut> fmt::Debug for SimGeneratorFn<Args, Fut> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
// use for compile-time side-effect
|
||||
let _ = Self::ASSERT_F_IS_ZERO_SIZED;
|
||||
let Self { args, f: _ } = self;
|
||||
f.debug_struct("SimGeneratorFn")
|
||||
.field("args", args)
|
||||
|
|
@ -4114,39 +4080,25 @@ impl<Args: fmt::Debug, F: Copy + Fn(Args, ExternModuleSimulationState) -> Fut, F
|
|||
}
|
||||
}
|
||||
|
||||
impl<Args: Hash, F: Copy + Fn(Args, ExternModuleSimulationState) -> Fut, Fut> Hash
|
||||
for SimGeneratorFn<Args, F, Fut>
|
||||
{
|
||||
impl<Args: Hash, Fut> Hash for SimGeneratorFn<Args, Fut> {
|
||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||
// use for compile-time side-effect
|
||||
let _ = Self::ASSERT_F_IS_ZERO_SIZED;
|
||||
let Self { args, f: _ } = self;
|
||||
let Self { args, f } = self;
|
||||
args.hash(state);
|
||||
f.hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
impl<Args: Eq, F: Copy + Fn(Args, ExternModuleSimulationState) -> Fut, Fut> Eq
|
||||
for SimGeneratorFn<Args, F, Fut>
|
||||
{
|
||||
}
|
||||
impl<Args: Eq, Fut> Eq for SimGeneratorFn<Args, Fut> {}
|
||||
|
||||
impl<Args: PartialEq, F: Copy + Fn(Args, ExternModuleSimulationState) -> Fut, Fut> PartialEq
|
||||
for SimGeneratorFn<Args, F, Fut>
|
||||
{
|
||||
impl<Args: PartialEq, Fut> PartialEq for SimGeneratorFn<Args, Fut> {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
// use for compile-time side-effect
|
||||
let _ = Self::ASSERT_F_IS_ZERO_SIZED;
|
||||
let Self { args, f: _ } = self;
|
||||
*args == other.args
|
||||
let Self { args, f } = self;
|
||||
*args == other.args && ptr::fn_addr_eq(*f, other.f)
|
||||
}
|
||||
}
|
||||
|
||||
impl<Args: Clone, F: Copy + Fn(Args, ExternModuleSimulationState) -> Fut, Fut> Clone
|
||||
for SimGeneratorFn<Args, F, Fut>
|
||||
{
|
||||
impl<Args: Clone, Fut> Clone for SimGeneratorFn<Args, Fut> {
|
||||
fn clone(&self) -> Self {
|
||||
// use for compile-time side-effect
|
||||
let _ = Self::ASSERT_F_IS_ZERO_SIZED;
|
||||
Self {
|
||||
args: self.args.clone(),
|
||||
f: self.f,
|
||||
|
|
@ -4154,20 +4106,14 @@ impl<Args: Clone, F: Copy + Fn(Args, ExternModuleSimulationState) -> Fut, Fut> C
|
|||
}
|
||||
}
|
||||
|
||||
impl<Args: Copy, F: Copy + Fn(Args, ExternModuleSimulationState) -> Fut, Fut> Copy
|
||||
for SimGeneratorFn<Args, F, Fut>
|
||||
{
|
||||
}
|
||||
impl<Args: Copy, Fut> Copy for SimGeneratorFn<Args, Fut> {}
|
||||
|
||||
impl<
|
||||
Args: fmt::Debug + Clone + Eq + Hash + Send + Sync + 'static,
|
||||
F: Copy + Fn(Args, ExternModuleSimulationState) -> Fut + Send + Sync + 'static,
|
||||
T: fmt::Debug + Clone + Eq + Hash + Send + Sync + 'static,
|
||||
Fut: IntoFuture<Output = ()> + 'static,
|
||||
> ExternModuleSimGenerator for SimGeneratorFn<Args, F, Fut>
|
||||
> ExternModuleSimGenerator for SimGeneratorFn<T, Fut>
|
||||
{
|
||||
fn run<'a>(&'a self, sim: ExternModuleSimulationState) -> impl IntoFuture<Output = ()> + 'a {
|
||||
// use for compile-time side-effect
|
||||
let _ = Self::ASSERT_F_IS_ZERO_SIZED;
|
||||
(self.f)(self.args.clone(), sim)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue