6

I'm creating a macro called throw_error. I expected this to compile yet, it fails:

// Util structs + types ... // Util macros #[macro_export] macro_rules! throw_error { () => { RaptorexError { message: String::new(), line: line!(), file: file!().to_owned(), } }; ($($msg:tt),*) => { let mut final_msg = String::new(); $( final_msg.push_str(&format!("{} ", $msg)); )* // remove trailing whitespace final_msg.pop(); RaptorexError { message: final_msg, line: line!(), file: file!(), } } } // Util functions ... 

I get several errors from using the macro in my other code.

Erros:

error: macro expansion ignores token `final_msg` and any following --> /Users/henryboisdequin/Desktop/raptorex/raptorex_util/src/lib.rs:30:13 | 30 | final_msg.push_str(&format!("{} ", $msg)); | ^^^^^^^^^ | ::: compiler/src/parser/parser.rs:44:29 | 44 | _ => return Err(throw_error!("Unexpected token:", current_token)), | ------------------------------------------------- help: you might be missing a semicolon here: `;` | | | caused by the macro expansion here | = note: the usage of `throw_error!` is likely invalid in expression context error[E0658]: `let` expressions in this position are experimental --> compiler/src/parser/parser.rs:44:29 | 44 | _ => return Err(throw_error!("Unexpected token:", current_token)), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #53667 <https://github.com/rust-lang/rust/issues/53667> for more information = help: add `#![feature(let_chains)]` to the crate attributes to enable = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: `let` expressions are not supported here --> compiler/src/parser/parser.rs:44:29 | 44 | _ => return Err(throw_error!("Unexpected token:", current_token)), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: only supported directly in conditions of `if`- and `while`-expressions = note: as well as when nested within `&&` and parenthesis in those conditions = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) warning: unused imports: `DATA_TYPES`, `KEYWORDS` --> compiler/src/parser/parser.rs:3:28 | 3 | lexer::tokens::{Token, DATA_TYPES, KEYWORDS}, | ^^^^^^^^^^ ^^^^^^^^ | = note: `#[warn(unused_imports)]` on by default error[E0308]: mismatched types --> compiler/src/parser/parser.rs:44:29 | 44 | _ => return Err(throw_error!("Unexpected token:", current_token)), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `raptorex_util::RaptorexError`, found `bool` | = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 4 previous errors; 1 warning emitted 

What is the cause of these errors and how can I fix it?

1 Answer 1

3

You need another set of {}s so the macro creates a block containing the statements instead of the individual statements themselves:

#[macro_export] macro_rules! throw_error { () => { RaptorexError { message: String::new(), line: line!(), file: file!().to_owned(), } }; ($($msg:tt),*) => { { // <------------------ let mut final_msg = String::new(); $( final_msg.push_str(&format!("{} ", $msg)); )* // remove trailing whitespace final_msg.pop(); RaptorexError { message: final_msg, line: line!(), file: file!(), } } // <------------------- } } 

The {} in the (...) => {} is part of the macro syntax and isn't part of the generated code.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, it worked but how do I import the RaptorexError from inside the extra brackets. I'm having trouble with that.
You can use an absolute path (i.e. ::crate_name::some_path::RaptorexError) either directly or with a use declaration within the block.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.