Similarly to this question, I was stumped by a compiler macro expansion error.
The offending code was:
/// send a command and wait for the response
///
/// 'dirty' macro that relies on outside context
macro_rules! send_and_receive {
($cmd: expr, $response_pat:pat => $r_block:block) => {
send_command(&mut port, $cmd);
for i in 0..3 {
match receive_response(&mut port) {
$response_pat => $r_block,
r => {
eprintln!("got response: {r:?}");
continue;
}
};
}
panic!("missing response");
}
}
Where the expected arguments are an enum instance, and a 'match like' expression, like so:
send_and_receive!(
Command::Thing { field: value /* etc */ },
Response::ThingResponse { response_field1, /* ... */ } => {
do_stuff_here();
}
);
The issue was that the macro expands to 'loose expressions', without an enclosing block.
Adding it fixed the issue (because it creates a scope to be able to return from), like so: