I have a macro, which just generates an instance of a struct, as below:
macro_rules! foo {
() => {{
let baz_val = baz();
let bar_val = match bar() {
Ok(val) => val,
Err(err) => {
return Err(err);
}
};
Ok(Foo(baz_val, bar_val))
}};
}
As you can see, I do an early return in macro depending on bar()
function's result. That's, however, resolves as an error, saying:
Compiling playground v0.0.1 (/playground)
error[E0308]: mismatched types
--> src/main.rs:23:24
|
23 | return Err(err);
| ^^^^^^^^ expected `()`, found enum `Result`
...
32 | let foo_val = foo!();
| ------ in this macro invocation
|
= note: expected unit type `()`
found enum `Result<_, String>`
= note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
For more information about this error, try `rustc --explain E0308`.
Here's also the permalink to the playground that has full minimum reproducible sample.
I think the problem here is type inference. I'd like to return an instance of FooResult
in the sample, but the macro cannot infer it.
So, how do I early return and infer/define the return type in the declarative macros?
return
is used in functions not in macros. For the expected behaviour you can wrap the macro into a closure and call it inmediatly:
macro_rules! foo {
() => {{
(|| {
let baz_val = baz();
let bar_val = match bar() {
Ok(val) => val,
Err(err) => {
return Err(err);
}
};
Ok(Foo(baz_val, bar_val))
})()
}};
}