rwf2/Rocket

uri! scope resolution issues

Open

#1120 opened on Sep 6, 2019

View on GitHub
 (9 comments) (1 reaction) (0 assignees)Rust (25,738 stars) (1,645 forks)batch import
deficiencyhelp wanted

Description

Now that uri! internally uses macro_rules! instead of macro (#964), path resolution works differently. As far as I can tell this is a direct consequence of the fact that macro was hygienic with respect to paths, resolving them at the macro definition site i.e. the "target" route. In contrast macro_rules! is not hygienic for item paths (only locals), so paths are resolved in the invocation scope of the uri macro.

As a consequence, code such as this now fails to compile because PathBuf is not in scope at the uri! call:

#![feature(proc_macro_hygiene)]
#[macro_use] extern crate rocket;

#[get("/")]
fn hello() -> String {
    format!("Try going to {}", uri!(submodule::echo_path: "example/path"))
}

mod submodule {
    use std::path::PathBuf;

    #[get("/<path..>")]
    pub fn echo_path(path: PathBuf) -> String {
        path.display().to_string()
    }
}

fn main() {
    rocket::ignite().mount("/", routes![hello, submodule::echo_path]).launch();
}

The best possible solution for this issue is to use macro once it stabilizes, but that is pretty far off. If it works, we could try fudging some Spans in the generated macro_rules! macro. Another solution would be to use structs instead of a macro to encode the route information at compile time, but that is a much more significant rewrite of uri! that probably can't be done with the same feature set that is implemented now.

Contributor guide