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

use-ing anyhow::Ok interferes with generated code #388

Closed
mkosiba opened this issue Jun 28, 2022 · 3 comments · Fixed by #389
Closed

use-ing anyhow::Ok interferes with generated code #388

mkosiba opened this issue Jun 28, 2022 · 3 comments · Fixed by #389

Comments

@mkosiba
Copy link

mkosiba commented Jun 28, 2022

I'm filing the issue mostly because this results in a somewhat non-obvious error message.

Repro:

use anyhow::{Error, Ok};
use async_trait::async_trait;
use mockall::automock;

#[automock]
#[async_trait]
pub trait Foo {
    async fn bar<'a>(&self) -> Result<(), Error>;
}

Compiler error:

54 | #[automock]
   | ^^^^^^^^^^^
   | |
   | expected `&str`, found struct `anyhow::Error`
   | expected `Result<Result<(), anyhow::Error>, &'static str>` because of return type
   |
   = note: expected enum `Result<_, &'static str>`
              found enum `Result<_, anyhow::Error>`
   = note: this error originates in the attribute macro `automock` (in Nightly builds, run with -Z macro-backtrace for more info)

Changing the first line to use anyhow::Error; causes the issue to go away.

It seems like some of the generated code (like fn call_mut(&mut self) -> std::result::Result<Result<(), Error>, &'static str>) explicitly references std::result::Result while other bits (like returning Ok(__mockall_f())) rely on nobody being silly enough to import their own Ok.
Hopefully fixing this is as simple as having the generated code return a fully-qualified std::result::Result::Ok instead of just Ok.

@asomers
Copy link
Owner

asomers commented Jun 28, 2022

That's a very good guess. BTW, you can see the generated code by setting MOCKALL_DEBUG=1 when you build. Would you be able to check it?

@mkosiba
Copy link
Author

mkosiba commented Jun 28, 2022

Sure! Relevant bit of generated code:

        {
            Default, Expired,
            Mut(Box < dyn FnMut() -> Result < (), Error > + Send >),
            MutSt(:: mockall :: Fragile < Box < dyn FnMut() -> Result < (),
            Error > >>),
            Once(Box < dyn FnOnce() -> Result < (), Error > + Send >),
            OnceSt(:: mockall :: Fragile < Box < dyn FnOnce() -> Result < (),
            Error > >>), _Phantom(Box < dyn Fn() + Send >)
        } impl Rfunc
        {
            fn call_mut(& mut self,) -> std :: result :: Result < Result < (),
            Error >, & 'static str >
            {
                match self
                {
                    Rfunc :: Default =>
                    {
                        use :: mockall :: ReturnDefault ; :: mockall ::
                        DefaultReturner :: < Result < (), Error > > ::
                        return_default()
                    }, Rfunc :: Expired =>
                    { Err("called twice, but it returns by move") }, Rfunc ::
                    Mut(__mockall_f) => { Ok(__mockall_f()) }, Rfunc ::
                    MutSt(__mockall_f) => { Ok((__mockall_f.get_mut()) ()) },
                    Rfunc :: Once(_) =>
                    {
                        if let Rfunc :: Once(mut __mockall_f) = mem ::
                        replace(self, Rfunc :: Expired) { Ok(__mockall_f()) } else
                        { unreachable! () }
                    }, Rfunc :: OnceSt(_) =>
                    {
                        if let Rfunc :: OnceSt(mut __mockall_f) = mem ::
                        replace(self, Rfunc :: Expired)
                        { Ok((__mockall_f.into_inner()) ()) } else
                        { unreachable! () }
                    }, Rfunc :: _Phantom(_) => unreachable! ()
                }
            }
        }

@mkosiba
Copy link
Author

mkosiba commented Jun 28, 2022

I can also confirm that if I paste the generated code into my IDE I get the error and if I change Ok to std::result::Result::Ok the errors go away.

asomers added a commit that referenced this issue Jun 28, 2022
The `anyhow` create defines a function by this name, and the proc-macro
generated code was picking it up instead of the standard Result::Ok .

Fixes #388
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants