Mockall with Tokio Mutex

I'm having trouble with an in-progress crate that only uses tokio::sync::mutex, but fails to mock a trait containing the tokio version of Mutex, claiming that the std version is being used. I've created a repo with a minimum example that shows the failure to compile, despite the entire crate not having a single reference to std::sync::Mutex. Is anyone familiar with this, or is it a bug as I suspect?

https://github.com/brendano257/test_mockall_tokio_mutex

The compiler error is:

error[E0308]: mismatched types
   --> tests/mocks/mock_thing.rs:10:16
    |
6   | / mock! {
7   | |     pub MyThing {}
8   | |
9   | |     impl Thing for MyThing {
10  | |         fn new(shared: Arc<Mutex<String>>) -> Self;
    | |                ^^^^^^ expected `std::sync::Mutex<String>`, found `tokio::sync::Mutex<String>`
11  | |     }
12  | | }
    | |_- arguments to this method are incorrect

What do you get when you ask cargo to expand the mockall macro?

I'm guessing that mockall uses a Mutex for something internally and that it generates an import that shadows the import of the Tokio Mutex. So it's probably a bug.

Cargo-expand yields:

#![feature(prelude_import)]
#[prelude_import]
use std::prelude::rust_2021::*;
#[macro_use]
extern crate std;
use std::sync::Arc;
use tokio::sync::Mutex;
pub struct MyThing {
    shared: Arc<Mutex<String>>,
}
pub trait Thing {
    fn new(shared: Arc<Mutex<String>>) -> Self;
}
impl Thing for MyThing {
    fn new(shared: Arc<Mutex<String>>) -> Self {
        MyThing { shared }
    }
}

I didn't see the std::sync::Mutex as part of the prelude, but maybe I didn't dig deep enough. The author confirmed the issue and workaround (explictly mocking using tokio::sync::Mutex), and the rest of my issue is likely just my lack of mockall knowledge.

Thanks!

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.