You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I've been trying to work around #217 in a complex codebase and have a simplified reproduction of a related issue. In my case, the trait in question needs a generic type and lifetime (due to async code).
The following simplified example reproduces the issue:
structThing<'a>(&'a ());#[mockall::automock]traitSomething{/// Some method that needs a generic// This compiles fine#[mockall::concretize]fngeneric<R:AsRef<()> + 'static>(&self,r:R);/// Some method that needs an explicit lifetime// This compiles finefnreference<'a>(&self,thing:&Thing<'a>);/// Some method that needs an explicit lifetime **and** a generic// This errors#[mockall::concretize]fngeneric_and_reference<'a,R:AsRef<()> + 'static>(&self,thing:Thing<'a>,r:R);}
Compilation of this example errors on the third method with a lifetime error:
error[E0261]: use of undeclared lifetime name `'a`
--> src/lib.rs:14:78
|
3 | #[mockall::automock]
| - - help: consider introducing lifetime `'a` here: `<'a>`
| |
| lifetime `'a` is missing in item created through this procedural macro
...
14 | fn generic_and_reference<'a, R: AsRef<()> + 'static>(&self, thing: Thing<'a>, r: R);
| ^^ undeclared lifetime
error[E0261]: use of undeclared lifetime name `'a`
--> src/lib.rs:14:78
|
3 | #[mockall::automock]
| -
| |
| lifetime `'a` is missing in item created through this procedural macro
| help: consider introducing lifetime `'a` here: `<'a>`
...
14 | fn generic_and_reference<'a, R: AsRef<()> + 'static>(&self, thing: Thing<'a>, r: R);
| ^^ undeclared lifetime
error[E0261]: use of undeclared lifetime name `'a`
--> src/lib.rs:14:78
|
3 | #[mockall::automock]
| - lifetime `'a` is missing in item created through this procedural macro
...
14 | fn generic_and_reference<'a, R: AsRef<()> + 'static>(&self, thing: Thing<'a>, r: R);
| ^^ undeclared lifetime
|
= note: for more information on higher-ranked polymorphism, visit https://doc.rust-lang.org/nomicon/hrtb.html
help: consider making the bound lifetime-generic with a new `'a` lifetime
|
3 | for<'a> #[mockall::automock]
| +++++++
help: consider introducing lifetime `'a` here
|
3 | #[mockall::automock]'a,
| +++
help: consider introducing lifetime `'a` here
|
3 | #[mockall::automock]<'a>
| ++++
For more information about this error, try `rustc --explain E0261`.
Looking at the macro expansion, it looks like concretize removed the generic lifetime.
So the problem is that #[concretize] doesn't work on functions with lifetime parameters. That's unsurprising. There are a billion special cases involving lifetime parameters.
Would you oppose a PR that fixes this particular case? If so, do you have any hints/pointers to share for a first time contributor to mockall (but proficient in Rust)? I'd create a test case based off of mockall/tests/automock_concretize_closures.rs and attempt to make it pass while getting to know the mockall codebase.
#610 should probably be fixed before this one. And I think that the first step towards fixing #610 would be to track the mock struct's Generics separately from the trait's. Then generating the code might be as simple as substituting the mock struct's generics in the appropriate places. To make #[concretize] work, we would have to then do some substitutions in both the trait generics and the struct generics.
I've been trying to work around #217 in a complex codebase and have a simplified reproduction of a related issue. In my case, the trait in question needs a generic type and lifetime (due to async code).
The following simplified example reproduces the issue:
Compilation of this example errors on the third method with a lifetime error:
Looking at the macro expansion, it looks like
concretize
removed the generic lifetime.The text was updated successfully, but these errors were encountered: