Search code examples
rustmacrosrust-cargoworkspacerust-rocket

Failed compilation of the rust project with a custom structure and the use of macros


I'm starting to learn rust and playing with the structure of the project. Now I have such a project structure :

project
└─── src
│   └─── core
│   │   └─── lib.rs
│   │   └─── Cargo.toml
│   └─── api
│       └─── main.rs
│       └─── Cargo.toml
└─── Cargo.toml

The contents of the toml files are as follows:
project/Cargo.toml

[workspace]
members = [ 
    "src/core", 
    "src/api"
]

project/src/api/Cargo.toml

[package]
name = "api"
version = "0.1.0"

[[bin]]
name = "api"
path = "main.rs"

[dependencies]
core = { path = "../core" }
rocket =  { version = "0.5.0", features = ["json"] } 

With these settings, the project is not compiled if in main.rs I'm trying to work with rocket macros. main.rs (the code is taken from the description of the rocket package):

#[macro_use] extern crate rocket;

#[get("/<name>/<age>")]
fn hello(name: &str, age: u8) -> String {
    format!("Hello, {} year old named {}!", age, name)
}

#[launch]
fn rocket() -> _ {
    rocket::build().mount("/hello", routes![hello])
}

I get an error:

error: macro-expanded `macro_export` macros from the current crate cannot be referred to by absolute paths
 --> src\api\main.rs:4:4
  |
4 | fn hello(name: &str, age: u8) -> String {
  |    ^^^^^
  |
  = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
  = note: for more information, see issue #52234 <https://github.com/rust-lang/rust/issues/52234>     
note: the macro is defined here
 --> src\api\main.rs:3:1
  |
3 | #[get("/<name>/<age>")]
  | ^^^^^^^^^^^^^^^^^^^^^^^
  = note: `#[deny(macro_expanded_macro_exports_accessed_by_absolute_paths)]` on by default
  = note: this error originates in the attribute macro `get` (in Nightly builds, run with -Z macro-backtrace for more info)

error: could not compile `api` (bin "api") due to 1 previous error

What is the reason for this and how can it be fixed?

But

I tried to create an api project with the src folder, this problem does not repeat.

api
└─── src
│   └─── main.rs
└─── Cargo.toml

But I don't want to keep the src folders for each project (main and lib) because workspace already has src. What can be done about it?


Solution

  • Looks like the Rocket docs haven't been updated in a while because the #[macro_use] syntax was phased out in Rust 1.30. Simply import these macros via the use declaration like so:

    use rocket::{get, launch, routes};
    
    #[get("/<name>/<age>")]
    fn hello(name: &str, age: u8) -> String {
        format!("Hello, {} year old named {}!", age, name)
    }
    
    #[launch]
    fn rocket() -> _ {
        rocket::build().mount("/hello", routes![hello])
    }
    

    This code compiles.