Skip to content

Commit

Permalink
Fixed compilation of latest nightly
Browse files Browse the repository at this point in the history
- Caused by `Fn` and related traits now requiring their arguments to
  impl `Tuple`. (PR: rust-lang/rust#99943)
- This PR adds constraints where needed to also require `Tuple` to be
  implemented.
- Also the feature gate `const_fn` no longer exists and was causing a
  compilation error, and this PR also removes its usage.
- Not very familiar with the internals of this crate, so please let me
  know if this PR should fix anything differently!
  • Loading branch information
BGluth committed Nov 9, 2022
1 parent 510e289 commit 25830e5
Show file tree
Hide file tree
Showing 4 changed files with 14 additions and 14 deletions.
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#![feature(fn_traits, unboxed_closures)]
#![feature(fn_traits, tuple_trait, unboxed_closures)]

//! Mocking framework for Rust (currently only nightly)
//!
Expand Down
14 changes: 7 additions & 7 deletions src/mock_store.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::mocking::MockResult;
use std::any::TypeId;
use std::{any::TypeId, marker::Tuple};
use std::cell::RefCell;
use std::collections::HashMap;
use std::mem::transmute;
Expand Down Expand Up @@ -32,7 +32,7 @@ impl MockStore {
self.layers.borrow_mut().pop();
}

pub unsafe fn add_to_thread_layer<I, O>(
pub unsafe fn add_to_thread_layer<I: Tuple, O>(
&self,
id: TypeId,
mock: Box<dyn FnMut<I, Output = MockResult<I, O>> + 'static>,
Expand All @@ -44,7 +44,7 @@ impl MockStore {
.add(id, mock);
}

pub unsafe fn call<I, O>(&self, id: TypeId, mut input: I) -> MockResult<I, O> {
pub unsafe fn call<I: Tuple, O>(&self, id: TypeId, mut input: I) -> MockResult<I, O> {
// Do not hold RefCell borrow while calling mock, it can try to modify mocks
let layer_count = self.layers.borrow().len();
for layer_idx in (0..layer_count).rev() {
Expand Down Expand Up @@ -93,7 +93,7 @@ impl MockLayer {
self.mocks.remove(&id);
}

pub unsafe fn add<I, O>(
pub unsafe fn add<I: Tuple, O>(
&mut self,
id: TypeId,
mock: Box<dyn FnMut<I, Output = MockResult<I, O>> + 'static>,
Expand All @@ -118,19 +118,19 @@ struct ErasedStoredMock {
}

impl ErasedStoredMock {
unsafe fn call<I, O>(self, input: I) -> MockLayerResult<I, O> {
unsafe fn call<I: Tuple, O>(self, input: I) -> MockLayerResult<I, O> {
let unerased: StoredMock<I, O> = transmute(self.mock);
unerased.call(input)
}
}

/// Guarantees that while mock is running it's not overwritten, destroyed, or called again
#[derive(Clone)]
struct StoredMock<I, O> {
struct StoredMock<I: Tuple, O> {
mock: Rc<RefCell<Box<dyn FnMut<I, Output = MockResult<I, O>>>>>,
}

impl<I, O> StoredMock<I, O> {
impl<I: Tuple, O> StoredMock<I, O> {
fn new(mock: Box<dyn FnMut<I, Output = MockResult<I, O>> + 'static>) -> Self {
StoredMock {
mock: Rc::new(RefCell::new(mock)),
Expand Down
10 changes: 5 additions & 5 deletions src/mocking.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::mock_store::{MockLayer, MockStore};
use std::any::{Any, TypeId};
use std::{any::{Any, TypeId}, marker::Tuple};
use std::marker::PhantomData;
use std::mem::transmute;

Expand All @@ -8,7 +8,7 @@ use std::mem::transmute;
/// The trait is implemented for all functions, so its methods can be called on any function.
///
/// Note: methods have any effect only if called on functions [annotated as mockable](https://docs.rs/mocktopus_macros).
pub trait Mockable<T, O> {
pub trait Mockable<T: Tuple, O> {
/// Core function for setting up mocks
///
/// Always consider using [mock_safe](#tymethod.mock_safe) or [MockContext](struct.MockContext.html).
Expand Down Expand Up @@ -97,7 +97,7 @@ pub fn clear_mocks() {
MOCK_STORE.with(|mock_store| mock_store.clear())
}

impl<T, O, F: FnOnce<T, Output = O>> Mockable<T, O> for F {
impl<T: Tuple, O, F: FnOnce<T, Output = O>> Mockable<T, O> for F {
unsafe fn mock_raw<M: FnMut<T, Output = MockResult<T, O>>>(&self, mock: M) {
let id = self.get_mock_id();
let boxed = Box::new(mock) as Box<dyn FnMut<_, Output = _>>;
Expand Down Expand Up @@ -186,7 +186,7 @@ impl<'a> MockContext<'a> {
///
/// This function doesn't actually mock the function. It registers it as a
/// function that will be mocked when [`run`](#method.run) is called.
pub fn mock_safe<I, O, F, M>(self, mockable: F, mock: M) -> Self
pub fn mock_safe<I: Tuple, O, F, M>(self, mockable: F, mock: M) -> Self
where
F: Mockable<I, O>,
M: FnMut<I, Output = MockResult<I, O>> + 'a,
Expand All @@ -198,7 +198,7 @@ impl<'a> MockContext<'a> {
///
/// This is an unsafe version of [`mock_safe`](#method.mock_safe),
/// without lifetime constraint on mock
pub unsafe fn mock_raw<I, O, F, M>(mut self, mockable: F, mock: M) -> Self
pub unsafe fn mock_raw<I: Tuple, O, F, M>(mut self, mockable: F, mock: M) -> Self
where
F: Mockable<I, O>,
M: FnMut<I, Output = MockResult<I, O>>,
Expand Down
2 changes: 1 addition & 1 deletion tests/injecting.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#![feature(const_fn, proc_macro_hygiene)]
#![feature(proc_macro_hygiene)]

// Test if injecting works even if mocktopus is aliased
extern crate mocktopus as mocktopus_aliased;
Expand Down

0 comments on commit 25830e5

Please sign in to comment.