It doesn't have any result on how the macro is used, it only serves to improve the quality of error messages when the macro is used incorrectly by telling the compiler that the output of the macro is always a single expression, not an item or multiple expressions.
The specific error that this was added to improve was for using vec![]
in a pattern match, which is invalid (you can't structually match on a Vec
):
let x: Option<Vec<i32>> = Some(vec![]);
match x {
Some(my_vec![]) => println!("1"),
_ => println!("2"),
};
results in
error[E0164]: expected tuple struct or tuple variant, found associated function `Vec::new`
--> src/main.rs:9:9
|
9 | Vec::new()
| ^^^^^^^^^^ `fn` calls are not allowed in patterns
...
15 | Some(my_vec![]) => println!("1"),
| --------- in this macro invocation
|
= help: for more information, visit https://doc.rust-lang.org/book/ch18-00-patterns.html
= note: this error originates in the macro `mvec` (in Nightly builds, run with -Z macro-backtrace for more info)
This is a fairly confusing error, especially when using the vec![1, 2, 3]
syntax. It doesn't look like are any function calls in the caller. But by wrapping the body of vec!
with __rust_force_expr
, we get a better error:
error: arbitrary expressions aren't allowed in patterns
--> src/main.rs:15:10
|
15 | Some(vec![]) => println!("1"),
| ^^^^^^
|
= note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info)
This makes a lot more sense: vec![]
produces an expression, and there are no reference to function calls that are behind a macro.