Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Self in function pointer arguments #450

Open
TimeToogo opened this issue Jan 17, 2023 · 1 comment
Open

Support Self in function pointer arguments #450

TimeToogo opened this issue Jan 17, 2023 · 1 comment
Labels
enhancement New feature or request

Comments

@TimeToogo
Copy link

Sample code:

#[cfg(test)]
use mockall::{automock, mock, predicate::*};

#[cfg_attr(test, automock)]
pub trait Example : Sized {
    fn register_callback<F: Fn(Self) + 'static>(&self, cb: F);
}

Produces 16 errors:

   Compiling mockall-repro v0.1.0 (/Users/elliotlevin/tmp/mockall-repro)
warning: unused import: `mock`
 --> src/lib.rs:2:25
  |
2 | use mockall::{automock, mock, predicate::*};
  |                         ^^^^
  |
  = note: `#[warn(unused_imports)]` on by default

error[E0308]: mismatched types
 --> src/lib.rs:6:56
  |
4 | #[cfg_attr(test, automock)]
  |                  -------- arguments to this function are incorrect
5 | pub trait Example : Sized{
6 |     fn register_callback<F: Fn(Self) + 'static>(&self, cb: F);
  |                                                        ^^ expected enum `Matcher`, found struct `Common`
  |
  = note: expected reference `&Box<(dyn Fn(Matcher) + 'static)>`
             found reference `&Box<(dyn Fn(Common) + 'static)>`
note: associated function defined here
 --> src/lib.rs:4:18
  |
4 | #[cfg_attr(test, automock)]
  |                  ^^^^^^^^
  = note: this error originates in the attribute macro `automock` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: the trait bound `MockallMatcher0: Predicate<Box<(dyn Fn(Matcher) + 'static)>>` is not satisfied
 --> src/lib.rs:4:18
  |
4 | #[cfg_attr(test, automock)]
  |                  ^^^^^^^^ the trait `Predicate<Box<(dyn Fn(Matcher) + 'static)>>` is not implemented for `MockallMatcher0`
  |
  = note: required for the cast from `MockallMatcher0` to the object type `dyn Predicate<Box<(dyn Fn(Matcher) + 'static)>> + Send`
  = note: this error originates in the attribute macro `automock` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider restricting type parameter `MockallMatcher0`
  |
4 | #[cfg_attr(test, automock mockall::Predicate<std::boxed::Box<(dyn std::ops::Fn(__mock_MockExample_Example::__register_callback::Matcher) + 'static)>>)]
  |                           +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

error[E0277]: expected a `Fn<(&Box<(dyn Fn(Matcher) + 'static)>,)>` closure, found `MockallF`
 --> src/lib.rs:4:18
  |
4 | #[cfg_attr(test, automock)]
  |                  ^^^^^^^^ expected an `Fn<(&Box<(dyn Fn(Matcher) + 'static)>,)>` closure, found `MockallF`
  |
  = note: expected a closure with arguments `(&Box<(dyn Fn(Common) + 'static)>,)`
             found a closure with arguments `(&Box<(dyn Fn(Matcher) + 'static)>,)`
  = note: required for the cast from `MockallF` to the object type `dyn for<'a> Fn(&'a Box<(dyn Fn(Matcher) + 'static)>) -> bool + Send`
  = note: this error originates in the attribute macro `automock` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: expected a `Fn<(&Box<(dyn Fn(Matcher) + 'static)>,)>` closure, found `MockallF`
 --> src/lib.rs:4:18
  |
4 | #[cfg_attr(test, automock)]
  |                  ^^^^^^^^ expected an `Fn<(&Box<(dyn Fn(Matcher) + 'static)>,)>` closure, found `MockallF`
  |
  = note: expected a closure with arguments `(&Box<(dyn Fn(Common) + 'static)>,)`
             found a closure with arguments `(&Box<(dyn Fn(Matcher) + 'static)>,)`
  = note: required for the cast from `MockallF` to the object type `dyn for<'a> Fn(&'a Box<(dyn Fn(Matcher) + 'static)>) -> bool`
  = note: this error originates in the attribute macro `automock` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0308]: mismatched types
 --> src/lib.rs:6:56
  |
4 | #[cfg_attr(test, automock)]
  |                  -------- arguments to this function are incorrect
5 | pub trait Example : Sized{
6 |     fn register_callback<F: Fn(Self) + 'static>(&self, cb: F);
  |                                                        ^^ expected enum `Rfunc`, found struct `Expectation`
  |
  = note: expected struct `Box<(dyn Fn(Rfunc) + 'static)>`
             found struct `Box<(dyn Fn(Expectation) + 'static)>`
note: associated function defined here
 --> src/lib.rs:4:18
  |
4 | #[cfg_attr(test, automock)]
  |                  ^^^^^^^^
  = note: this error originates in the attribute macro `automock` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: expected a `FnOnce<(Box<(dyn Fn(Rfunc) + 'static)>,)>` closure, found `MockallF`
 --> src/lib.rs:4:18
  |
4 | #[cfg_attr(test, automock)]
  |                  ^^^^^^^^ expected an `FnOnce<(Box<(dyn Fn(Rfunc) + 'static)>,)>` closure, found `MockallF`
  |
  = note: expected a closure with arguments `(Box<(dyn Fn(Expectation) + 'static)>,)`
             found a closure with arguments `(Box<(dyn Fn(Rfunc) + 'static)>,)`
  = note: required for the cast from `MockallF` to the object type `dyn FnOnce(Box<(dyn Fn(Rfunc) + 'static)>) + Send`
  = note: this error originates in the attribute macro `automock` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: expected a `FnOnce<(Box<(dyn Fn(Rfunc) + 'static)>,)>` closure, found `MockallF`
 --> src/lib.rs:4:18
  |
4 | #[cfg_attr(test, automock)]
  |                  ^^^^^^^^ expected an `FnOnce<(Box<(dyn Fn(Rfunc) + 'static)>,)>` closure, found `MockallF`
  |
  = note: expected a closure with arguments `(Box<(dyn Fn(Expectation) + 'static)>,)`
             found a closure with arguments `(Box<(dyn Fn(Rfunc) + 'static)>,)`
  = note: required for the cast from `MockallF` to the object type `dyn FnOnce(Box<(dyn Fn(Rfunc) + 'static)>)`
  = note: this error originates in the attribute macro `automock` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: expected a `FnMut<(Box<(dyn Fn(Rfunc) + 'static)>,)>` closure, found `MockallF`
 --> src/lib.rs:4:18
  |
4 | #[cfg_attr(test, automock)]
  |                  ^^^^^^^^ expected an `FnMut<(Box<(dyn Fn(Rfunc) + 'static)>,)>` closure, found `MockallF`
  |
  = note: expected a closure with arguments `(Box<(dyn Fn(Expectation) + 'static)>,)`
             found a closure with arguments `(Box<(dyn Fn(Rfunc) + 'static)>,)`
  = note: required for the cast from `MockallF` to the object type `dyn FnMut(Box<(dyn Fn(Rfunc) + 'static)>) + Send`
  = note: this error originates in the attribute macro `automock` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: expected a `FnMut<(Box<(dyn Fn(Rfunc) + 'static)>,)>` closure, found `MockallF`
 --> src/lib.rs:4:18
  |
4 | #[cfg_attr(test, automock)]
  |                  ^^^^^^^^ expected an `FnMut<(Box<(dyn Fn(Rfunc) + 'static)>,)>` closure, found `MockallF`
  |
  = note: expected a closure with arguments `(Box<(dyn Fn(Expectation) + 'static)>,)`
             found a closure with arguments `(Box<(dyn Fn(Rfunc) + 'static)>,)`
  = note: required for the cast from `MockallF` to the object type `dyn FnMut(Box<(dyn Fn(Rfunc) + 'static)>)`
  = note: this error originates in the attribute macro `automock` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0308]: mismatched types
 --> src/lib.rs:6:56
  |
4 | #[cfg_attr(test, automock)]
  |                  -------- arguments to this function are incorrect
5 | pub trait Example : Sized{
6 |     fn register_callback<F: Fn(Self) + 'static>(&self, cb: F);
  |                                                        ^^ expected struct `Common`, found struct `Expectation`
  |
  = note: expected reference `&Box<(dyn Fn(Common) + 'static)>`
             found reference `&Box<(dyn Fn(Expectation) + 'static)>`
note: associated function defined here
 --> src/lib.rs:4:18
  |
4 | #[cfg_attr(test, automock)]
  |                  ^^^^^^^^
  = note: this error originates in the attribute macro `automock` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: the trait bound `MockallMatcher0: Predicate<Box<(dyn Fn(Common) + 'static)>>` is not satisfied
 --> src/lib.rs:6:56
  |
4 | #[cfg_attr(test, automock)]
  |                  -------- required by a bound introduced by this call
5 | pub trait Example : Sized{
6 |     fn register_callback<F: Fn(Self) + 'static>(&self, cb: F);
  |                                                        ^^ the trait `Predicate<Box<(dyn Fn(Common) + 'static)>>` is not implemented for `MockallMatcher0`
  |
note: required by a bound in `Common::with`
 --> src/lib.rs:4:18
  |
4 | #[cfg_attr(test, automock)]
  |                  ^^^^^^^^ required by this bound in `Common::with`
  = note: this error originates in the attribute macro `automock` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider restricting type parameter `MockallMatcher0`
  |
4 | #[cfg_attr(test, automock mockall::Predicate<std::boxed::Box<(dyn std::ops::Fn(__mock_MockExample_Example::__register_callback::Common) + 'static)>>)]
  |                           ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

error[E0277]: expected a `Fn<(&Box<(dyn Fn(Common) + 'static)>,)>` closure, found `MockallF`
 --> src/lib.rs:4:18
  |
4 | #[cfg_attr(test, automock)]
  |                  ^^^^^^^^ expected an `Fn<(&Box<(dyn Fn(Common) + 'static)>,)>` closure, found `MockallF`
  |
  = note: expected a closure with arguments `(&Box<(dyn Fn(Expectation) + 'static)>,)`
             found a closure with arguments `(&Box<(dyn Fn(Common) + 'static)>,)`
note: required by a bound in `Common::withf`
 --> src/lib.rs:4:18
  |
4 | #[cfg_attr(test, automock)]
  |                  ^^^^^^^^ required by this bound in `Common::withf`
  = note: this error originates in the attribute macro `automock` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: expected a `Fn<(&Box<(dyn Fn(Common) + 'static)>,)>` closure, found `MockallF`
 --> src/lib.rs:4:18
  |
4 | #[cfg_attr(test, automock)]
  |                  ^^^^^^^^ expected an `Fn<(&Box<(dyn Fn(Common) + 'static)>,)>` closure, found `MockallF`
  |
  = note: expected a closure with arguments `(&Box<(dyn Fn(Expectation) + 'static)>,)`
             found a closure with arguments `(&Box<(dyn Fn(Common) + 'static)>,)`
note: required by a bound in `Common::withf_st`
 --> src/lib.rs:4:18
  |
4 | #[cfg_attr(test, automock)]
  |                  ^^^^^^^^ required by this bound in `Common::withf_st`
  = note: this error originates in the attribute macro `automock` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0308]: mismatched types
 --> src/lib.rs:4:18
  |
4 | #[cfg_attr(test, automock)]
  |                  ^^^^^^^^
  |                  |
  |                  expected struct `Expectation`, found struct `Expectations`
  |                  arguments to this function are incorrect
  |
  = note: expected reference `&Box<(dyn Fn(Expectation) + 'static)>`
             found reference `&Box<(dyn Fn(Expectations) + 'static)>`
note: associated function defined here
 --> src/lib.rs:4:18
  |
4 | #[cfg_attr(test, automock)]
  |                  ^^^^^^^^
  = note: this error originates in the attribute macro `automock` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0308]: mismatched types
 --> src/lib.rs:6:56
  |
4 | #[cfg_attr(test, automock)]
  |                  -------- arguments to this function are incorrect
5 | pub trait Example : Sized{
6 |     fn register_callback<F: Fn(Self) + 'static>(&self, cb: F);
  |                                                        ^^ expected struct `Expectation`, found struct `Expectations`
  |
  = note: expected struct `Box<(dyn Fn(Expectation) + 'static)>`
             found struct `Box<(dyn Fn(Expectations) + 'static)>`
note: associated function defined here
 --> src/lib.rs:4:18
  |
4 | #[cfg_attr(test, automock)]
  |                  ^^^^^^^^
  = note: this error originates in the attribute macro `automock` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: expected a `Fn<(Expectations,)>` closure, found `F`
 --> src/lib.rs:4:18
  |
4 | #[cfg_attr(test, automock)]
  |                  ^^^^^^^^ expected an `Fn<(Expectations,)>` closure, found `F`
  |
  = note: expected a closure with arguments `(MockExample,)`
             found a closure with arguments `(Expectations,)`
  = note: required for the cast from `F` to the object type `dyn Fn(Expectations)`
  = note: this error originates in the attribute macro `automock` (in Nightly builds, run with -Z macro-backtrace for more info)

Some errors have detailed explanations: E0277, E0308.
For more information about an error, try `rustc --explain E0277`.
warning: `mockall-repro` (lib test) generated 1 warning
error: could not compile `mockall-repro` due to 16 previous errors; 1 warning emitted

This seems to apply the same for &Self, &mut Self, etc.
I'm wondering if this is unsupported by mockall or a bug?

@asomers
Copy link
Owner

asomers commented Jan 17, 2023

Mockall doesn't support Self in that position. It could, with some extra work. But if you don't want to wait, here is a workaround:

use mockall::{automock, mock, predicate::*};

pub trait Example: Sized {
    fn register_callback<F: Fn(Self) + 'static>(&self, cb: F);
}

mock! {
    pub Example {}
    impl Example for Example {
        fn register_callback<F: Fn(MockExample) + 'static>(&self, cb: F);
    }
}

@asomers asomers added the enhancement New feature or request label Jan 17, 2023
@asomers asomers changed the title #[automock] returns error for generic Fn with Self param Support Self in function pointer arguments Jan 17, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants